Extracted JokerObject and CardObject common functionalities to SpriteObject, removing duplicate code and dangerous casts.
This commit is contained in:
+6
-12
@@ -45,17 +45,7 @@ typedef struct
|
||||
typedef struct
|
||||
{
|
||||
Card *card;
|
||||
Sprite *sprite;
|
||||
FIXED tx, ty; // target position
|
||||
FIXED x, y; // position
|
||||
FIXED vx, vy; // velocity
|
||||
FIXED tscale;
|
||||
FIXED scale;
|
||||
FIXED vscale;
|
||||
FIXED trotation; // this never gets used so i might remove it later
|
||||
FIXED rotation;
|
||||
FIXED vrotation;
|
||||
bool selected;
|
||||
SpriteObject *sprite_object;
|
||||
} CardObject;
|
||||
|
||||
// Card functions
|
||||
@@ -71,6 +61,10 @@ CardObject *card_object_new(Card *card);
|
||||
void card_object_destroy(CardObject **card_object);
|
||||
void card_object_update(CardObject *card_object); // Update the card object position and scale
|
||||
void card_object_set_sprite(CardObject *card_object, int layer);
|
||||
void card_object_shake(CardObject *card_object, mm_word sound_id); // This doesn't actually score anything, it just performs an animation and plays a sound effect
|
||||
void card_object_shake(CardObject* card_object, mm_word sound_id);
|
||||
|
||||
void card_object_set_selected(CardObject* card_object, bool selected);
|
||||
bool card_object_is_selected(CardObject* card_object);
|
||||
Sprite* card_object_get_sprite(CardObject* card_object);
|
||||
|
||||
#endif // CARD_H
|
||||
@@ -50,8 +50,6 @@ typedef struct
|
||||
int bottom;
|
||||
} Rect;
|
||||
|
||||
#define UNDEFINED -1
|
||||
|
||||
/* Gets the screenblock tile for the given coordinates (x, y).
|
||||
* x and y are in number of tiles.
|
||||
* Returns the screenblock tile.
|
||||
|
||||
+6
-15
@@ -42,22 +42,8 @@ typedef struct
|
||||
|
||||
typedef struct // copy of CardObject in card.h
|
||||
{
|
||||
/* Note that since JokerObject is cast to CardObject in joker_object_update(),
|
||||
* they have to have the exact same structure to have
|
||||
* the exact same field offsets in memory
|
||||
*/
|
||||
Joker *joker;
|
||||
Sprite *sprite;
|
||||
FIXED tx, ty;
|
||||
FIXED x, y;
|
||||
FIXED vx, vy;
|
||||
FIXED tscale;
|
||||
FIXED scale;
|
||||
FIXED vscale;
|
||||
FIXED trotation;
|
||||
FIXED rotation;
|
||||
FIXED vrotation;
|
||||
bool selected;
|
||||
SpriteObject* sprite_object;
|
||||
} JokerObject;
|
||||
|
||||
typedef struct // These jokers are triggered after the played hand has finished scoring.
|
||||
@@ -84,4 +70,9 @@ void joker_object_update(JokerObject *joker_object);
|
||||
void joker_object_shake(JokerObject *joker_object, mm_word sound_id); // This doesn't actually score anything, it just performs an animation and plays a sound effect
|
||||
bool joker_object_score(JokerObject *joker_object, Card* scored_card, int *chips, int *mult, int *xmult, int *money, bool *retrigger); // This scores the joker and returns true if it was scored successfully (Card = NULL means the joker is independent and not scored by a card)
|
||||
|
||||
void joker_object_set_selected(JokerObject* joker_object, bool selected);
|
||||
bool joker_object_is_selected(JokerObject* joker_object);
|
||||
|
||||
Sprite* joker_object_get_sprite(JokerObject* joker_object);
|
||||
|
||||
#endif // JOKER_H
|
||||
@@ -2,6 +2,7 @@
|
||||
#define SPRITE_H
|
||||
|
||||
#include <tonc.h>
|
||||
#include <maxmod.h>
|
||||
|
||||
typedef struct
|
||||
{
|
||||
@@ -11,6 +12,22 @@ typedef struct
|
||||
POINT pos;
|
||||
} Sprite;
|
||||
|
||||
// A sprite object is a sprite that is selectable and movable in animation
|
||||
typedef struct
|
||||
{
|
||||
Sprite* sprite;
|
||||
FIXED tx, ty; // target position
|
||||
FIXED x, y; // position
|
||||
FIXED vx, vy; // velocity
|
||||
FIXED tscale;
|
||||
FIXED scale;
|
||||
FIXED vscale;
|
||||
FIXED trotation; // this never gets used so i might remove it later
|
||||
FIXED rotation;
|
||||
FIXED vrotation;
|
||||
bool selected;
|
||||
} SpriteObject;
|
||||
|
||||
// Sprite methods
|
||||
Sprite *sprite_new(u16 a0, u16 a1, u32 tid, u32 pb, int sprite_index);
|
||||
Sprite *affine_sprite_new(u16 a0, u16 a1, u32 tid, u32 pb);
|
||||
@@ -28,4 +45,17 @@ INLINE void sprite_position(Sprite *sprite, int x, int y)
|
||||
void sprite_init();
|
||||
void sprite_draw();
|
||||
|
||||
// SpriteObject methods
|
||||
SpriteObject *sprite_object_new();
|
||||
void sprite_object_destroy(SpriteObject **sprite_object);
|
||||
void sprite_object_set_sprite(SpriteObject* sprite_object, Sprite* sprite);
|
||||
void sprite_object_reset_transform(SpriteObject* sprite_object);
|
||||
void sprite_object_update(SpriteObject *sprite_object);
|
||||
void sprite_object_shake(SpriteObject* sprite_object, mm_word sound_id);
|
||||
|
||||
void sprite_object_set_selected(SpriteObject* sprite_object, bool selected);
|
||||
bool sprite_object_is_selected(SpriteObject* sprite_object);
|
||||
Sprite* sprite_object_get_sprite(SpriteObject* sprite_object);
|
||||
|
||||
|
||||
#endif // SPRITE_H
|
||||
@@ -33,4 +33,6 @@ static inline int get_digits_even(int n)
|
||||
return 5;
|
||||
}
|
||||
|
||||
#define UNDEFINED -1
|
||||
|
||||
#endif // UTIL_H
|
||||
+29
-78
@@ -64,20 +64,7 @@ CardObject *card_object_new(Card *card)
|
||||
CardObject *card_object = malloc(sizeof(CardObject));
|
||||
|
||||
card_object->card = card;
|
||||
card_object->sprite = NULL;
|
||||
card_object->tx = 0; // Target position
|
||||
card_object->ty = 0;
|
||||
card_object->x = 0;
|
||||
card_object->y = 0;
|
||||
card_object->vx = 0;
|
||||
card_object->vy = 0;
|
||||
card_object->tscale = float2fx(1.0f); // Target scale
|
||||
card_object->scale = float2fx(1.0f);
|
||||
card_object->vscale = float2fx(0.0f);
|
||||
card_object->trotation = 0; // Target rotation
|
||||
card_object->rotation = 0;
|
||||
card_object->vrotation = 0;
|
||||
card_object->selected = false;
|
||||
card_object->sprite_object = sprite_object_new();
|
||||
|
||||
return card_object;
|
||||
}
|
||||
@@ -85,83 +72,47 @@ CardObject *card_object_new(Card *card)
|
||||
void card_object_destroy(CardObject **card_object)
|
||||
{
|
||||
if (*card_object == NULL) return;
|
||||
sprite_destroy(&(*card_object)->sprite);
|
||||
sprite_object_destroy(&((*card_object)->sprite_object));
|
||||
//card_destroy(&(*card_object)->card); // In practice, this is unnecessary because the card will be inserted into the discard pile and then back into the deck. If you need to destroy the card, you can do it manually before calling this function.
|
||||
free(*card_object);
|
||||
*card_object = NULL;
|
||||
}
|
||||
|
||||
void card_object_update(CardObject *card_object)
|
||||
void card_object_update(CardObject* card_object)
|
||||
{
|
||||
card_object->vx += (card_object->tx - card_object->x) / 8;
|
||||
card_object->vy += (card_object->ty - card_object->y) / 8;
|
||||
|
||||
card_object->vscale += (card_object->tscale - card_object->scale) / 8; // Scale up the card when it's played
|
||||
|
||||
card_object->vrotation += (card_object->trotation - card_object->rotation) / 8; // Rotate the card when it's played
|
||||
|
||||
// set velocity to 0 if it's close enough to the target
|
||||
const float epsilon = float2fx(0.01f);
|
||||
if (card_object->vx < epsilon && card_object->vx > -epsilon && card_object->vy < epsilon && card_object->vy > -epsilon)
|
||||
{
|
||||
card_object->vx = 0;
|
||||
card_object->vy = 0;
|
||||
|
||||
card_object->x = card_object->tx;
|
||||
card_object->y = card_object->ty;
|
||||
}
|
||||
else
|
||||
{
|
||||
card_object->vx = (card_object->vx * 7) / 10;
|
||||
card_object->vy = (card_object->vy * 7) / 10;
|
||||
|
||||
card_object->x += card_object->vx;
|
||||
card_object->y += card_object->vy;
|
||||
}
|
||||
|
||||
// Set scale to 0 if it's close enough to the target
|
||||
if (card_object->vscale < epsilon && card_object->vscale > -epsilon)
|
||||
{
|
||||
card_object->vscale = 0;
|
||||
card_object->scale = card_object->tscale; // Set the scale to the target scale
|
||||
}
|
||||
else
|
||||
{
|
||||
card_object->vscale = (card_object->vscale * 7) / 10;
|
||||
card_object->scale += card_object->vscale;
|
||||
}
|
||||
|
||||
// Set rotation to 0 if it's close enough to the target
|
||||
if (card_object->vrotation < epsilon && card_object->vrotation > -epsilon)
|
||||
{
|
||||
card_object->vrotation = 0;
|
||||
card_object->rotation = card_object->trotation; // Set the rotation to the target rotation
|
||||
}
|
||||
else
|
||||
{
|
||||
card_object->vrotation = (card_object->vrotation * 7) / 10;
|
||||
card_object->rotation += card_object->vrotation;
|
||||
}
|
||||
|
||||
obj_aff_rotscale(card_object->sprite->aff, card_object->scale, card_object->scale, -card_object->vx + card_object->rotation); // Apply rotation and scale to the sprite
|
||||
sprite_position(card_object->sprite, fx2int(card_object->x), fx2int(card_object->y));
|
||||
if (card_object == NULL) return;
|
||||
sprite_object_update(card_object->sprite_object);
|
||||
}
|
||||
|
||||
void card_object_set_sprite(CardObject *card_object, int layer)
|
||||
{
|
||||
int tile_index = CARD_TID + (layer * CARD_SPRITE_OFFSET);
|
||||
memcpy32(&tile_mem[4][tile_index], &deck_gfxTiles[card_sprite_lut[card_object->card->suit][card_object->card->rank] * TILE_SIZE], TILE_SIZE * CARD_SPRITE_OFFSET);
|
||||
sprite_destroy(&card_object->sprite); // Destroy the old sprite if it exists
|
||||
card_object->sprite = sprite_new(ATTR0_SQUARE | ATTR0_4BPP | ATTR0_AFF, ATTR1_SIZE_32, tile_index, 0, layer + CARD_STARTING_LAYER);
|
||||
sprite_object_set_sprite(card_object->sprite_object, sprite_new(ATTR0_SQUARE | ATTR0_4BPP | ATTR0_AFF, ATTR1_SIZE_32, tile_index, 0, layer + CARD_STARTING_LAYER));
|
||||
}
|
||||
|
||||
void card_object_shake(CardObject *card_object, mm_word sound_id)
|
||||
void card_object_shake(CardObject* card_object, mm_word sound_id)
|
||||
{
|
||||
card_object->vscale = float2fx(0.3f); // Scale down the card when it's scored
|
||||
card_object->vrotation = float2fx(8.0f); // Rotate the card when it's scored
|
||||
|
||||
if (sound_id == -1) return; // If no sound ID is provided, do nothing
|
||||
|
||||
mm_sound_effect sfx_select = {{sound_id}, 1024, 0, 255, 128,};
|
||||
mmEffectEx(&sfx_select);
|
||||
sprite_object_shake(card_object->sprite_object, sound_id);
|
||||
}
|
||||
|
||||
void card_object_set_selected(CardObject* card_object, bool selected)
|
||||
{
|
||||
if (card_object == NULL)
|
||||
return;
|
||||
sprite_object_set_selected(card_object->sprite_object, selected);
|
||||
}
|
||||
|
||||
bool card_object_is_selected(CardObject* card_object)
|
||||
{
|
||||
if (card_object == NULL)
|
||||
return false;
|
||||
return sprite_object_is_selected(card_object->sprite_object);
|
||||
}
|
||||
|
||||
Sprite* card_object_get_sprite(CardObject* card_object)
|
||||
{
|
||||
if (card_object == NULL)
|
||||
return NULL;
|
||||
return sprite_object_get_sprite(card_object->sprite_object);
|
||||
}
|
||||
|
||||
+82
-84
@@ -204,6 +204,7 @@ static const Rect SHOP_REROLL_RECT = {88, 96, UNDEFINED, UNDEFI
|
||||
|
||||
//TODO: Properly define and use
|
||||
#define MENU_POP_OUT_ANIM_FRAMES 20
|
||||
#define SCORED_CARD_TEXT_Y 48
|
||||
|
||||
// General functions
|
||||
void set_seed(int seed)
|
||||
@@ -265,7 +266,8 @@ void sort_cards()
|
||||
{
|
||||
if (hand[i] != NULL)
|
||||
{
|
||||
sprite_destroy(&hand[i]->sprite);
|
||||
// card_object_get_sprite() will not work here since we need the address
|
||||
sprite_destroy(&(hand[i]->sprite_object->sprite));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -275,7 +277,7 @@ void sort_cards()
|
||||
{
|
||||
//hand[i]->sprite = sprite_new(ATTR0_SQUARE | ATTR0_4BPP | ATTR0_AFF, ATTR1_SIZE_32, card_sprite_lut[hand[i]->card->suit][hand[i]->card->rank], 0, i);
|
||||
card_object_set_sprite(hand[i], i); // Set the sprite for the card object
|
||||
sprite_position(hand[i]->sprite, fx2int(hand[i]->x), fx2int(hand[i]->y));
|
||||
sprite_position(card_object_get_sprite(hand[i]), fx2int(hand[i]->sprite_object->x), fx2int(hand[i]->sprite_object->y));
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -298,7 +300,7 @@ enum HandType hand_get_type()
|
||||
|
||||
for (int i = 0; i <= hand_top; i++)
|
||||
{
|
||||
if (hand[i] != NULL && hand[i]->selected)
|
||||
if (hand[i] != NULL && card_object_is_selected(hand[i]))
|
||||
{
|
||||
suits[hand[i]->card->suit]++;
|
||||
ranks[hand[i]->card->rank]++;
|
||||
@@ -628,7 +630,7 @@ void change_background(int id)
|
||||
background = id;
|
||||
}
|
||||
|
||||
void set_temp_score(int value)
|
||||
void display_temp_score(int value)
|
||||
{
|
||||
int x_offset = 40 - get_digits_even(value) * TILE_SIZE;
|
||||
tte_erase_rect_wrapper(TEMP_SCORE_RECT);
|
||||
@@ -805,8 +807,8 @@ void card_draw()
|
||||
const FIXED deck_x = int2fx(208);
|
||||
const FIXED deck_y = int2fx(110);
|
||||
|
||||
card_object->x = deck_x;
|
||||
card_object->y = deck_y;
|
||||
card_object->sprite_object->x = deck_x;
|
||||
card_object->sprite_object->y = deck_y;
|
||||
|
||||
hand[++hand_top] = card_object;
|
||||
|
||||
@@ -831,9 +833,9 @@ void hand_select()
|
||||
{
|
||||
if (hand_state != HAND_SELECT || hand[selection_x] == NULL) return;
|
||||
|
||||
if (hand[selection_x]->selected)
|
||||
if (card_object_is_selected(hand[selection_x]))
|
||||
{
|
||||
hand[selection_x]->selected = false;
|
||||
card_object_set_selected(hand[selection_x], false);
|
||||
hand_selections--;
|
||||
|
||||
mm_sound_effect sfx_select = {{SFX_CARD_SELECT}, 1024, 0, 255, 128,};
|
||||
@@ -841,7 +843,7 @@ void hand_select()
|
||||
}
|
||||
else if (hand_selections < MAX_SELECTION_SIZE)
|
||||
{
|
||||
hand[selection_x]->selected = true;
|
||||
card_object_set_selected(hand[selection_x], true);
|
||||
hand_selections++;
|
||||
|
||||
mm_sound_effect sfx_deselect = {{SFX_CARD_DESELECT}, 1024, 0, 255, 128,};
|
||||
@@ -1139,7 +1141,7 @@ static void game_playing_process_input_and_state()
|
||||
lerped_temp_score = int2fx(temp_score);
|
||||
lerped_score = int2fx(score);
|
||||
|
||||
set_temp_score(temp_score);
|
||||
display_temp_score(temp_score);
|
||||
|
||||
chips = 0;
|
||||
mult = 0;
|
||||
@@ -1154,7 +1156,7 @@ static void game_playing_process_input_and_state()
|
||||
|
||||
if (lerped_temp_score > 0)
|
||||
{
|
||||
set_temp_score(fx2int(lerped_temp_score));
|
||||
display_temp_score(fx2int(lerped_temp_score));
|
||||
|
||||
// We actually don't need to erase this because the score only increases
|
||||
display_score(fx2int(lerped_score)); // Set the score display
|
||||
@@ -1210,16 +1212,12 @@ static void game_playing_discarded_cards_loop()
|
||||
discarded_card_object = card_object_new(discard_pop());
|
||||
//discarded_card_object->sprite = sprite_new(ATTR0_SQUARE | ATTR0_4BPP | ATTR0_AFF, ATTR1_SIZE_32, card_sprite_lut[discarded_card_object->card->suit][discarded_card_object->card->rank], 0, 0);
|
||||
card_object_set_sprite(discarded_card_object, 0); // Set the sprite for the discarded card object
|
||||
discarded_card_object->tx = int2fx(204);
|
||||
discarded_card_object->ty = int2fx(112);
|
||||
discarded_card_object->x = int2fx(240);
|
||||
discarded_card_object->y = int2fx(80);
|
||||
discarded_card_object->vx = 0;
|
||||
discarded_card_object->vy = 0;
|
||||
discarded_card_object->scale = float2fx(1.0f);
|
||||
discarded_card_object->vscale = float2fx(0.0f);
|
||||
discarded_card_object->rotation = 0;
|
||||
discarded_card_object->vrotation = 0;
|
||||
sprite_object_reset_transform(discarded_card_object->sprite_object);
|
||||
|
||||
discarded_card_object->sprite_object->tx = int2fx(204);
|
||||
discarded_card_object->sprite_object->ty = int2fx(112);
|
||||
discarded_card_object->sprite_object->x = int2fx(240);
|
||||
discarded_card_object->sprite_object->y = int2fx(80);
|
||||
|
||||
card_object_update(discarded_card_object);
|
||||
}
|
||||
@@ -1227,7 +1225,7 @@ static void game_playing_discarded_cards_loop()
|
||||
{
|
||||
card_object_update(discarded_card_object);
|
||||
|
||||
if (discarded_card_object->y >= discarded_card_object->ty)
|
||||
if (discarded_card_object->sprite_object->y >= discarded_card_object->sprite_object->ty)
|
||||
{
|
||||
deck_push(discarded_card_object->card); // Put the card back into the deck
|
||||
card_object_destroy(&discarded_card_object);
|
||||
@@ -1265,23 +1263,23 @@ static void cards_in_hand_update_loop(bool* discarded_card, int* played_selectio
|
||||
case HAND_SELECT:
|
||||
bool is_focused = (i == selection_x && selection_y == 0);
|
||||
|
||||
if (is_focused && !hand[i]->selected)
|
||||
if (is_focused && !card_object_is_selected(hand[i]))
|
||||
{
|
||||
hand_y -= int2fx(10);
|
||||
}
|
||||
else if (!is_focused && hand[i]->selected)
|
||||
else if (!is_focused && card_object_is_selected(hand[i]))
|
||||
{
|
||||
hand_y -= int2fx(15);
|
||||
}
|
||||
else if (is_focused && hand[i]->selected)
|
||||
else if (is_focused && card_object_is_selected(hand[i]))
|
||||
{
|
||||
hand_y -= int2fx(20);
|
||||
}
|
||||
|
||||
if (i != selection_x && hand[i]->y > hand_y)
|
||||
if (i != selection_x && hand[i]->sprite_object->y > hand_y)
|
||||
{
|
||||
hand[i]->y = hand_y;
|
||||
hand[i]->vy = 0;
|
||||
hand[i]->sprite_object->y = hand_y;
|
||||
hand[i]->sprite_object->vy = 0;
|
||||
}
|
||||
|
||||
hand_x = hand_x + (int2fx(i) - int2fx(hand_top) / 2) * -spacing_lut[hand_top]; // TODO: Change this later to reference a 2D LUT of positions
|
||||
@@ -1289,7 +1287,7 @@ static void cards_in_hand_update_loop(bool* discarded_card, int* played_selectio
|
||||
case HAND_SHUFFLING:
|
||||
/* FALL THROUGH */
|
||||
case HAND_DISCARD: // TODO: Add sound
|
||||
if (hand[i]->selected || hand_state == HAND_SHUFFLING)
|
||||
if (card_object_is_selected(hand[i]) || hand_state == HAND_SHUFFLING)
|
||||
{
|
||||
if (!*discarded_card)
|
||||
{
|
||||
@@ -1304,7 +1302,7 @@ static void cards_in_hand_update_loop(bool* discarded_card, int* played_selectio
|
||||
*sound_played = true;
|
||||
}
|
||||
|
||||
if (hand[i]->x >= hand_x)
|
||||
if (hand[i]->sprite_object->x >= hand_x)
|
||||
{
|
||||
discard_push(hand[i]->card);
|
||||
card_object_destroy(&hand[i]);
|
||||
@@ -1315,8 +1313,8 @@ static void cards_in_hand_update_loop(bool* discarded_card, int* played_selectio
|
||||
*sound_played = false;
|
||||
timer = 0;
|
||||
|
||||
hand_y = hand[i]->y;
|
||||
hand_x = hand[i]->x;
|
||||
hand_y = hand[i]->sprite_object->y;
|
||||
hand_x = hand[i]->sprite_object->x;
|
||||
}
|
||||
|
||||
*discarded_card = true;
|
||||
@@ -1354,11 +1352,11 @@ static void cards_in_hand_update_loop(bool* discarded_card, int* played_selectio
|
||||
hand_x = hand_x + (int2fx(i) - int2fx(hand_top) / 2) * -spacing_lut[hand_top];
|
||||
hand_y += int2fx(24);
|
||||
|
||||
if (hand[i]->selected && *discarded_card == false && timer % FRAMES(10) == 0)
|
||||
if (card_object_is_selected(hand[i]) && *discarded_card == false && timer % FRAMES(10) == 0)
|
||||
{
|
||||
hand[i]->selected = false;
|
||||
card_object_set_selected(hand[i], false);
|
||||
played_push(hand[i]);
|
||||
sprite_destroy(&hand[i]->sprite);
|
||||
sprite_destroy(&hand[i]->sprite_object->sprite);
|
||||
hand[i] = NULL;
|
||||
sort_cards();
|
||||
|
||||
@@ -1396,7 +1394,7 @@ static void cards_in_hand_update_loop(bool* discarded_card, int* played_selectio
|
||||
}
|
||||
}
|
||||
|
||||
played[highest_rank_index]->selected = true;
|
||||
card_object_set_selected(played[highest_rank_index], true);
|
||||
break;
|
||||
case PAIR: // find two cards with the same rank (Requires recursion)
|
||||
for (int i = 0; i <= played_top - 1; i++)
|
||||
@@ -1405,13 +1403,13 @@ static void cards_in_hand_update_loop(bool* discarded_card, int* played_selectio
|
||||
{
|
||||
if (played[i]->card->rank == played[j]->card->rank)
|
||||
{
|
||||
played[i]->selected = true;
|
||||
played[j]->selected = true;
|
||||
card_object_set_selected(played[i], true);
|
||||
card_object_set_selected(played[j], true);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (played[i]->selected) break;
|
||||
if (card_object_is_selected(played[i])) break;
|
||||
}
|
||||
break;
|
||||
case TWO_PAIR: // find two pairs of cards with the same rank (Requires recursion)
|
||||
@@ -1423,24 +1421,24 @@ static void cards_in_hand_update_loop(bool* discarded_card, int* played_selectio
|
||||
{
|
||||
if (played[i]->card->rank == played[j]->card->rank)
|
||||
{
|
||||
played[i]->selected = true;
|
||||
played[j]->selected = true;
|
||||
card_object_set_selected(played[i], true);
|
||||
card_object_set_selected(played[j], true);
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (played[i]->selected) break;
|
||||
if (card_object_is_selected(played[i])) break;
|
||||
}
|
||||
|
||||
for (; i <= played_top - 1; i++) // Find second pair
|
||||
{
|
||||
for (int j = i + 1; j <= played_top; j++)
|
||||
{
|
||||
if (played[i]->card->rank == played[j]->card->rank && played[i]->selected == false && played[j]->selected == false)
|
||||
if (played[i]->card->rank == played[j]->card->rank && !card_object_is_selected(played[i]) && !card_object_is_selected(played[j]))
|
||||
{
|
||||
played[i]->selected = true;
|
||||
played[j]->selected = true;
|
||||
card_object_set_selected(played[i], true);
|
||||
card_object_set_selected(played[j], true);
|
||||
break;
|
||||
}
|
||||
}
|
||||
@@ -1453,14 +1451,14 @@ static void cards_in_hand_update_loop(bool* discarded_card, int* played_selectio
|
||||
{
|
||||
if (played[i]->card->rank == played[j]->card->rank)
|
||||
{
|
||||
played[i]->selected = true;
|
||||
played[j]->selected = true;
|
||||
card_object_set_selected(played[i], true);
|
||||
card_object_set_selected(played[j], true);
|
||||
|
||||
for (int k = j + 1; k <= played_top; k++)
|
||||
{
|
||||
if (played[i]->card->rank == played[k]->card->rank && played[k]->selected == false)
|
||||
if (played[i]->card->rank == played[k]->card->rank && !card_object_is_selected(played[k]))
|
||||
{
|
||||
played[k]->selected = true;
|
||||
card_object_set_selected(played[k], true);
|
||||
break;
|
||||
}
|
||||
}
|
||||
@@ -1469,7 +1467,7 @@ static void cards_in_hand_update_loop(bool* discarded_card, int* played_selectio
|
||||
}
|
||||
}
|
||||
|
||||
if (played[i]->selected) break;
|
||||
if (card_object_is_selected(played[i])) break;
|
||||
}
|
||||
break;
|
||||
case FOUR_OF_A_KIND: // find four cards with the same rank (requires recursion)
|
||||
@@ -1490,7 +1488,7 @@ static void cards_in_hand_update_loop(bool* discarded_card, int* played_selectio
|
||||
{
|
||||
if (i != unmatched_index)
|
||||
{
|
||||
played[i]->selected = true;
|
||||
card_object_set_selected(played[i], true);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1498,7 +1496,7 @@ static void cards_in_hand_update_loop(bool* discarded_card, int* played_selectio
|
||||
{
|
||||
for (int i = 0; i <= played_top; i++)
|
||||
{
|
||||
played[i]->selected = true;
|
||||
card_object_set_selected(played[i], true);
|
||||
}
|
||||
}
|
||||
break;
|
||||
@@ -1519,7 +1517,7 @@ static void cards_in_hand_update_loop(bool* discarded_card, int* played_selectio
|
||||
case FLUSH_FIVE: // Select all played cards in the hand (This is functionally identical as the above hand types)
|
||||
for (int i = 0; i <= played_top; i++)
|
||||
{
|
||||
played[i]->selected = true;
|
||||
card_object_set_selected(played[i], true);
|
||||
}
|
||||
break;
|
||||
}
|
||||
@@ -1532,8 +1530,8 @@ static void cards_in_hand_update_loop(bool* discarded_card, int* played_selectio
|
||||
break;
|
||||
}
|
||||
|
||||
hand[i]->tx = hand_x;
|
||||
hand[i]->ty = hand_y;
|
||||
hand[i]->sprite_object->tx = hand_x;
|
||||
hand[i]->sprite_object->ty = hand_y;
|
||||
card_object_update(hand[i]);
|
||||
}
|
||||
}
|
||||
@@ -1547,7 +1545,7 @@ static void played_cards_update_loop(bool* discarded_card, int* played_selection
|
||||
{
|
||||
if (played[i] != NULL)
|
||||
{
|
||||
if (played[i]->sprite == NULL)
|
||||
if (card_object_get_sprite(played[i]) == NULL)
|
||||
{
|
||||
//played[i]->sprite = sprite_new(ATTR0_SQUARE | ATTR0_4BPP | ATTR0_AFF, ATTR1_SIZE_32, card_sprite_lut[played[i]->card->suit][played[i]->card->rank], 0, i + MAX_HAND_SIZE);
|
||||
card_object_set_sprite(played[i], i + MAX_HAND_SIZE); // Set the sprite for the played card object
|
||||
@@ -1562,7 +1560,7 @@ static void played_cards_update_loop(bool* discarded_card, int* played_selection
|
||||
switch (play_state)
|
||||
{
|
||||
case PLAY_PLAYING:
|
||||
if (i == 0 && (timer % FRAMES(10) == 0 || played[played_top - *played_selections]->selected == false) && timer > FRAMES(40))
|
||||
if (i == 0 && (timer % FRAMES(10) == 0 || !card_object_is_selected(played[played_top - *played_selections])) && timer > FRAMES(40))
|
||||
{
|
||||
(*played_selections)--;
|
||||
|
||||
@@ -1573,7 +1571,7 @@ static void played_cards_update_loop(bool* discarded_card, int* played_selection
|
||||
}
|
||||
}
|
||||
|
||||
if (played[i]->selected && played_top - i >= *played_selections)
|
||||
if (card_object_is_selected(played[i]) && played_top - i >= *played_selections)
|
||||
{
|
||||
played_y -= int2fx(10);
|
||||
}
|
||||
@@ -1602,7 +1600,7 @@ static void played_cards_update_loop(bool* discarded_card, int* played_selection
|
||||
}
|
||||
}
|
||||
|
||||
if (played[j]->selected)
|
||||
if (card_object_is_selected(played[j]))
|
||||
{
|
||||
scored_cards = j + 1; // Count the number of cards that have been scored
|
||||
if (scored_cards > *played_selections)
|
||||
@@ -1615,7 +1613,7 @@ static void played_cards_update_loop(bool* discarded_card, int* played_selection
|
||||
}
|
||||
}
|
||||
|
||||
tte_set_pos(fx2int(played[j]->x) + 8, 48); // Offset of 16 pixels to center the text on the card
|
||||
tte_set_pos(fx2int(played[j]->sprite_object->x) + 8, SCORED_CARD_TEXT_Y); // Offset of 16 pixels to center the text on the card
|
||||
tte_set_special(0xD000); // Set text color to blue from background memory
|
||||
|
||||
// Write the score to a character buffer variable
|
||||
@@ -1666,13 +1664,13 @@ static void played_cards_update_loop(bool* discarded_card, int* played_selection
|
||||
}
|
||||
}
|
||||
|
||||
if (played[i]->selected)
|
||||
if (card_object_is_selected(played[i]))
|
||||
{
|
||||
played_y -= int2fx(10);
|
||||
}
|
||||
break;
|
||||
case PLAY_ENDING: // This is the reverse of PLAY_PLAYING. The cards get reset back to their neutral position sequentially
|
||||
if (i == 0 && (timer % FRAMES(10) == 0 || played[played_top - *played_selections]->selected == false) && timer > FRAMES(40))
|
||||
if (i == 0 && (timer % FRAMES(10) == 0 || !card_object_is_selected(played[played_top - *played_selections])) && timer > FRAMES(40))
|
||||
{
|
||||
(*played_selections)--;
|
||||
|
||||
@@ -1683,7 +1681,7 @@ static void played_cards_update_loop(bool* discarded_card, int* played_selection
|
||||
}
|
||||
}
|
||||
|
||||
if (played[i]->selected && played_top - i <= *played_selections - 1)
|
||||
if (card_object_is_selected(played[i]) && played_top - i <= *played_selections - 1)
|
||||
{
|
||||
played_y -= int2fx(10);
|
||||
}
|
||||
@@ -1702,7 +1700,7 @@ static void played_cards_update_loop(bool* discarded_card, int* played_selection
|
||||
*sound_played = true;
|
||||
}
|
||||
|
||||
if (played[i]->x >= played_x)
|
||||
if (played[i]->sprite_object->x >= played_x)
|
||||
{
|
||||
discard_push(played[i]->card); // Push the card to the discard pile
|
||||
card_object_destroy(&played[i]);
|
||||
@@ -1743,9 +1741,9 @@ static void played_cards_update_loop(bool* discarded_card, int* played_selection
|
||||
break;
|
||||
}
|
||||
|
||||
played[i]->tx = played_x;
|
||||
played[i]->ty = played_y;
|
||||
played[i]->tscale = played_scale;
|
||||
played[i]->sprite_object->tx = played_x;
|
||||
played[i]->sprite_object->ty = played_y;
|
||||
played[i]->sprite_object->tscale = played_scale;
|
||||
card_object_update(played[i]);
|
||||
}
|
||||
}
|
||||
@@ -1767,12 +1765,12 @@ static void held_jokers_update_loop()
|
||||
|
||||
for (int i = jokers_top; i >= 0; i--)
|
||||
{
|
||||
jokers[i]->tx = hand_x - int2fx(spacing_lut[jokers_top][i]);
|
||||
jokers[i]->ty = hand_y;
|
||||
jokers[i]->sprite_object->tx = hand_x - int2fx(spacing_lut[jokers_top][i]);
|
||||
jokers[i]->sprite_object->ty = hand_y;
|
||||
|
||||
if (jokers[i]->selected)
|
||||
if (joker_object_is_selected(jokers[i]))
|
||||
{
|
||||
jokers[i]->ty -= int2fx(10);
|
||||
jokers[i]->sprite_object->ty -= int2fx(10);
|
||||
}
|
||||
|
||||
joker_object_update(jokers[i]);
|
||||
@@ -1830,22 +1828,22 @@ static void game_shop_create_items(JokerObject *shop_jokers[], bool first_time)
|
||||
u8 joker_id = random() % MAX_JOKERS;
|
||||
|
||||
shop_jokers[i] = joker_object_new(joker_new(joker_id));
|
||||
shop_jokers[i]->x = int2fx(120 + i * 32);
|
||||
shop_jokers[i]->y = int2fx(160);
|
||||
shop_jokers[i]->tx = shop_jokers[i]->x;
|
||||
shop_jokers[i]->ty = int2fx(71);
|
||||
shop_jokers[i]->sprite_object->x = int2fx(120 + i * 32);
|
||||
shop_jokers[i]->sprite_object->y = int2fx(160);
|
||||
shop_jokers[i]->sprite_object->tx = shop_jokers[i]->sprite_object->x;
|
||||
shop_jokers[i]->sprite_object->ty = int2fx(71);
|
||||
|
||||
int x = fx2int(shop_jokers[i]->tx) + TILE_SIZE - (get_digits_even(shop_jokers[i]->joker->value) - 1) * TILE_SIZE;
|
||||
int y = fx2int(shop_jokers[i]->ty);
|
||||
int x = fx2int(shop_jokers[i]->sprite_object->tx) + TILE_SIZE - (get_digits_even(shop_jokers[i]->joker->value) - 1) * TILE_SIZE;
|
||||
int y = fx2int(shop_jokers[i]->sprite_object->ty);
|
||||
tte_printf("#{P:%d,%d; cx:0xC000}$%d", x, y, shop_jokers[i]->joker->value);
|
||||
|
||||
if (first_time == false)
|
||||
{
|
||||
shop_jokers[i]->y = shop_jokers[i]->ty; // If it's not the first time, set the y position to the target position
|
||||
shop_jokers[i]->sprite_object->y = shop_jokers[i]->sprite_object->ty; // If it's not the first time, set the y position to the target position
|
||||
joker_object_shake(shop_jokers[i], UNDEFINED); // Give the joker a little wiggle animation
|
||||
}
|
||||
|
||||
sprite_position(shop_jokers[i]->sprite, fx2int(shop_jokers[i]->x), fx2int(shop_jokers[i]->y));
|
||||
sprite_position(joker_object_get_sprite(shop_jokers[i]), fx2int(shop_jokers[i]->sprite_object->x), fx2int(shop_jokers[i]->sprite_object->y));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2317,7 +2315,7 @@ void game_shop()
|
||||
{
|
||||
if (i == selection_x - 1 && selection_y == 0)
|
||||
{
|
||||
shop_jokers[i]->ty = int2fx(61);
|
||||
shop_jokers[i]->sprite_object->ty = int2fx(61);
|
||||
|
||||
if (key_hit(SELECT_CARD) && jokers_top < MAX_JOKERS_HELD_SIZE - 1 && money >= shop_jokers[i]->joker->value)
|
||||
{
|
||||
@@ -2326,8 +2324,8 @@ void game_shop()
|
||||
display_money(money); // Update the money display
|
||||
|
||||
Rect joker_price_rect;
|
||||
joker_price_rect.left = fx2int(shop_jokers[i]->tx);
|
||||
joker_price_rect.top = fx2int(shop_jokers[i]->ty) + TILE_SIZE;
|
||||
joker_price_rect.left = fx2int(shop_jokers[i]->sprite_object->tx);
|
||||
joker_price_rect.top = fx2int(shop_jokers[i]->sprite_object->ty) + TILE_SIZE;
|
||||
joker_price_rect.right = joker_price_rect.left + TILE_SIZE * 3;
|
||||
joker_price_rect.bottom = joker_price_rect.top + TILE_SIZE;
|
||||
|
||||
@@ -2338,7 +2336,7 @@ void game_shop()
|
||||
}
|
||||
else
|
||||
{
|
||||
shop_jokers[i]->ty = int2fx(71);
|
||||
shop_jokers[i]->sprite_object->ty = int2fx(71);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -2360,7 +2358,7 @@ void game_shop()
|
||||
{
|
||||
if (shop_jokers[i] != NULL)
|
||||
{
|
||||
shop_jokers[i]->ty = int2fx(160);
|
||||
shop_jokers[i]->sprite_object->ty = int2fx(160);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+43
-28
@@ -10,8 +10,11 @@
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#define JOKER_SCORE_TEXT_Y 48
|
||||
|
||||
const static u8 joker_data_lut[MAX_JOKERS][2] = // Rarity, Value
|
||||
{
|
||||
// TODO: Change to struct
|
||||
{COMMON_JOKER, 2}, // Default Joker
|
||||
{COMMON_JOKER, 5}, // Greedy Joker
|
||||
};
|
||||
@@ -33,6 +36,7 @@ const static u8 edition_price_lut[MAX_EDITIONS] =
|
||||
since I'm lazy and sorting them wouldn't look good enough to warrant the effort.
|
||||
*/
|
||||
static bool used_layers[MAX_JOKER_OBJECTS] = {false}; // Track used layers for joker sprites
|
||||
// TODO: Refactor sorting into SpriteObject?
|
||||
|
||||
void joker_init()
|
||||
{
|
||||
@@ -99,31 +103,24 @@ JokerObject *joker_object_new(Joker *joker)
|
||||
}
|
||||
|
||||
joker_object->joker = joker;
|
||||
joker_object->sprite_object = sprite_object_new();
|
||||
|
||||
int tile_index = JOKER_TID + (layer * JOKER_SPRITE_OFFSET);
|
||||
memcpy32(&tile_mem[4][tile_index], &joker_gfxTiles[joker->id * TILE_SIZE * JOKER_SPRITE_OFFSET], TILE_SIZE * JOKER_SPRITE_OFFSET);
|
||||
joker_object->sprite = sprite_new
|
||||
sprite_object_set_sprite
|
||||
(
|
||||
ATTR0_SQUARE | ATTR0_4BPP | ATTR0_AFF,
|
||||
ATTR1_SIZE_32,
|
||||
tile_index,
|
||||
JOKER_PB,
|
||||
JOKER_STARTING_LAYER + layer
|
||||
joker_object->sprite_object,
|
||||
sprite_new
|
||||
(
|
||||
ATTR0_SQUARE | ATTR0_4BPP | ATTR0_AFF,
|
||||
ATTR1_SIZE_32,
|
||||
tile_index,
|
||||
JOKER_PB,
|
||||
JOKER_STARTING_LAYER + layer
|
||||
)
|
||||
);
|
||||
|
||||
joker_object->tx = 0; // Target position
|
||||
joker_object->ty = 0;
|
||||
joker_object->x = 0;
|
||||
joker_object->y = 0;
|
||||
joker_object->vx = 0;
|
||||
joker_object->vy = 0;
|
||||
joker_object->tscale = float2fx(1.0f); // Target scale
|
||||
joker_object->scale = float2fx(1.0f);
|
||||
joker_object->vscale = float2fx(0.0f);
|
||||
joker_object->trotation = float2fx(0.0f); // Target rotation
|
||||
joker_object->rotation = float2fx(0.0f);
|
||||
joker_object->vrotation = float2fx(0.0f);
|
||||
joker_object->selected = false;
|
||||
|
||||
|
||||
return joker_object;
|
||||
}
|
||||
@@ -132,9 +129,9 @@ void joker_object_destroy(JokerObject **joker_object)
|
||||
{
|
||||
if (*joker_object == NULL) return;
|
||||
|
||||
int layer = sprite_get_layer((*joker_object)->sprite) - JOKER_STARTING_LAYER;
|
||||
int layer = sprite_get_layer(joker_object_get_sprite(*joker_object)) - JOKER_STARTING_LAYER;
|
||||
used_layers[layer] = false;
|
||||
sprite_destroy(&(*joker_object)->sprite); // Destroy the sprite
|
||||
sprite_object_destroy(&(*joker_object)->sprite_object); // Destroy the sprite
|
||||
joker_destroy(&(*joker_object)->joker); // Destroy the joker
|
||||
free(*joker_object);
|
||||
*joker_object = NULL;
|
||||
@@ -142,17 +139,13 @@ void joker_object_destroy(JokerObject **joker_object)
|
||||
|
||||
void joker_object_update(JokerObject *joker_object)
|
||||
{
|
||||
// Re-use the card object update logic by casting the JokerObject to a CardObject temporarily
|
||||
// This works because card_object_update doesn't use any card data, which is why CardObject should've been generic. my bad
|
||||
// TODO: Refactor and separate the relevant fields to a generic struct, maybe to Sprite or make a SpriteObject
|
||||
CardObject *card_object = (CardObject *)joker_object;
|
||||
card_object_update(card_object);
|
||||
}
|
||||
|
||||
void joker_object_shake(JokerObject *joker_object, mm_word sound_id)
|
||||
{
|
||||
CardObject *card_object = (CardObject *)joker_object;
|
||||
card_object_shake(card_object, sound_id);
|
||||
sprite_object_shake(joker_object->sprite_object, sound_id);
|
||||
}
|
||||
|
||||
bool joker_object_score(JokerObject *joker_object, Card* scored_card, int *chips, int *mult, int *xmult, int *money, bool *retrigger)
|
||||
@@ -169,7 +162,7 @@ bool joker_object_score(JokerObject *joker_object, Card* scored_card, int *chips
|
||||
*money += joker_effect.money;
|
||||
// TODO: Retrigger
|
||||
|
||||
tte_set_pos(fx2int(joker_object->x) + 8, 48); // Offset of 16 pixels to center the text on the card
|
||||
tte_set_pos(fx2int(joker_object->sprite_object->x) + 8, JOKER_SCORE_TEXT_Y); // Offset of 16 pixels to center the text on the card
|
||||
|
||||
char score_buffer[12];
|
||||
|
||||
@@ -198,4 +191,26 @@ bool joker_object_score(JokerObject *joker_object, Card* scored_card, int *chips
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void joker_object_set_selected(JokerObject* joker_object, bool selected)
|
||||
{
|
||||
if (joker_object == NULL)
|
||||
return;
|
||||
sprite_object_set_selected(joker_object->sprite_object, selected);
|
||||
}
|
||||
|
||||
bool joker_object_is_selected(JokerObject* joker_object)
|
||||
{
|
||||
if (joker_object == NULL)
|
||||
return false;
|
||||
return sprite_object_is_selected(joker_object->sprite_object);
|
||||
}
|
||||
|
||||
Sprite* joker_object_get_sprite(JokerObject* joker_object)
|
||||
{
|
||||
if (joker_object == NULL)
|
||||
return NULL;
|
||||
return sprite_object_get_sprite(joker_object->sprite_object);
|
||||
}
|
||||
|
||||
+134
-1
@@ -1,7 +1,9 @@
|
||||
#include "sprite.h"
|
||||
#include "util.h"
|
||||
|
||||
#include <tonc.h>
|
||||
#include <stdlib.h>
|
||||
#include <maxmod.h>
|
||||
|
||||
#define MAX_SPRITES 128
|
||||
#define MAX_AFFINES 32
|
||||
@@ -96,4 +98,135 @@ void sprite_draw()
|
||||
obj_copy(obj_mem, obj_buffer, MAX_SPRITES);
|
||||
obj_aff_copy(obj_aff_mem, obj_aff_buffer, MAX_AFFINES);
|
||||
oam_copy(oam_mem, obj_buffer, MAX_SPRITES);
|
||||
}
|
||||
}
|
||||
|
||||
// SpriteObject methods
|
||||
SpriteObject* sprite_object_new()
|
||||
{
|
||||
SpriteObject* sprite_object = (SpriteObject*)malloc(sizeof(SpriteObject));
|
||||
sprite_object->sprite = NULL;
|
||||
sprite_object_reset_transform(sprite_object);
|
||||
sprite_object->selected = false;
|
||||
|
||||
return sprite_object;
|
||||
}
|
||||
|
||||
void sprite_object_destroy(SpriteObject** sprite_object)
|
||||
{
|
||||
if (*sprite_object == NULL) return;
|
||||
sprite_destroy(&((*sprite_object)->sprite));
|
||||
free(*sprite_object);
|
||||
*sprite_object = NULL;
|
||||
}
|
||||
|
||||
void sprite_object_set_sprite(SpriteObject* sprite_object, Sprite* sprite)
|
||||
{
|
||||
if (sprite_object == NULL)
|
||||
return;
|
||||
sprite_destroy(&sprite_object->sprite); // Destroy the old sprite if it exists
|
||||
sprite_object->sprite = sprite;
|
||||
}
|
||||
|
||||
void sprite_object_reset_transform(SpriteObject* sprite_object)
|
||||
{
|
||||
sprite_object->tx = 0; // Target position
|
||||
sprite_object->ty = 0;
|
||||
sprite_object->x = 0;
|
||||
sprite_object->y = 0;
|
||||
sprite_object->vx = 0;
|
||||
sprite_object->vy = 0;
|
||||
sprite_object->tscale = float2fx(1.0f); // Target scale
|
||||
sprite_object->scale = float2fx(1.0f);
|
||||
sprite_object->vscale = float2fx(0.0f);
|
||||
sprite_object->trotation = 0; // Target rotation
|
||||
sprite_object->rotation = 0;
|
||||
sprite_object->vrotation = 0;
|
||||
}
|
||||
|
||||
void sprite_object_update(SpriteObject* sprite_object)
|
||||
{
|
||||
sprite_object->vx += (sprite_object->tx - sprite_object->x) / 8;
|
||||
sprite_object->vy += (sprite_object->ty - sprite_object->y) / 8;
|
||||
|
||||
sprite_object->vscale += (sprite_object->tscale - sprite_object->scale) / 8; // Scale up the card when it's played
|
||||
|
||||
sprite_object->vrotation += (sprite_object->trotation - sprite_object->rotation) / 8; // Rotate the card when it's played
|
||||
|
||||
// set velocity to 0 if it's close enough to the target
|
||||
const float epsilon = float2fx(0.01f);
|
||||
if (sprite_object->vx < epsilon && sprite_object->vx > -epsilon && sprite_object->vy < epsilon && sprite_object->vy > -epsilon)
|
||||
{
|
||||
sprite_object->vx = 0;
|
||||
sprite_object->vy = 0;
|
||||
|
||||
sprite_object->x = sprite_object->tx;
|
||||
sprite_object->y = sprite_object->ty;
|
||||
}
|
||||
else
|
||||
{
|
||||
sprite_object->vx = (sprite_object->vx * 7) / 10;
|
||||
sprite_object->vy = (sprite_object->vy * 7) / 10;
|
||||
|
||||
sprite_object->x += sprite_object->vx;
|
||||
sprite_object->y += sprite_object->vy;
|
||||
}
|
||||
|
||||
// Set scale to 0 if it's close enough to the target
|
||||
if (sprite_object->vscale < epsilon && sprite_object->vscale > -epsilon)
|
||||
{
|
||||
sprite_object->vscale = 0;
|
||||
sprite_object->scale = sprite_object->tscale; // Set the scale to the target scale
|
||||
}
|
||||
else
|
||||
{
|
||||
sprite_object->vscale = (sprite_object->vscale * 7) / 10;
|
||||
sprite_object->scale += sprite_object->vscale;
|
||||
}
|
||||
|
||||
// Set rotation to 0 if it's close enough to the target
|
||||
if (sprite_object->vrotation < epsilon && sprite_object->vrotation > -epsilon)
|
||||
{
|
||||
sprite_object->vrotation = 0;
|
||||
sprite_object->rotation = sprite_object->trotation; // Set the rotation to the target rotation
|
||||
}
|
||||
else
|
||||
{
|
||||
sprite_object->vrotation = (sprite_object->vrotation * 7) / 10;
|
||||
sprite_object->rotation += sprite_object->vrotation;
|
||||
}
|
||||
|
||||
obj_aff_rotscale(sprite_object->sprite->aff, sprite_object->scale, sprite_object->scale, -sprite_object->vx + sprite_object->rotation); // Apply rotation and scale to the sprite
|
||||
sprite_position(sprite_object->sprite, fx2int(sprite_object->x), fx2int(sprite_object->y));
|
||||
}
|
||||
|
||||
void sprite_object_shake(SpriteObject* sprite_object, mm_word sound_id)
|
||||
{
|
||||
sprite_object->vscale = float2fx(0.3f); // Scale down the card when it's scored
|
||||
sprite_object->vrotation = float2fx(8.0f); // Rotate the card when it's scored
|
||||
|
||||
if (sound_id == UNDEFINED) return; // If no sound ID is provided, do nothing
|
||||
|
||||
mm_sound_effect sfx_select = { {sound_id}, 1024, 0, 255, 128, };
|
||||
mmEffectEx(&sfx_select);
|
||||
}
|
||||
|
||||
void sprite_object_set_selected(SpriteObject* sprite_object, bool selected)
|
||||
{
|
||||
if (sprite_object == NULL)
|
||||
return;
|
||||
sprite_object->selected = selected;
|
||||
}
|
||||
|
||||
bool sprite_object_is_selected(SpriteObject* sprite_object)
|
||||
{
|
||||
if (sprite_object == NULL)
|
||||
return false;
|
||||
return sprite_object->selected;
|
||||
}
|
||||
|
||||
Sprite* sprite_object_get_sprite(SpriteObject* sprite_object)
|
||||
{
|
||||
if (sprite_object == NULL)
|
||||
return NULL;
|
||||
return sprite_object->sprite;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user