summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMenase Teshale <osome3717@gmail.com>2026-09-08 08:15:47 +0300
committerMenase Teshale <osome3717@gmail.com>2026-09-08 08:15:47 +0300
commit9dfdb7df2929fcfdf5f932b2e27499d3f0e5d412 (patch)
tree08416230e1313ea39fdb5980873e88feaa64a78a
parenta03a982c026a185d617d25e6a37ce939a481e946 (diff)
Working on timed mode logic
-rw-r--r--src/game.c107
1 files changed, 107 insertions, 0 deletions
diff --git a/src/game.c b/src/game.c
index bac0e6c..183f716 100644
--- a/src/game.c
+++ b/src/game.c
@@ -38,6 +38,15 @@
#define MAX_CLEARED_TILES_STORED 50
#define LOW_TIME_REMAINING 20 //In seconds
+#define CLEAR_EXTRA_TIME_BONUS 0.25
+
+#define TEXT_SPRITE_LENGTH 100
+#define TIMED_MODE_NUM_TIME_ADDED_SPRITES 4
+#define TIME_ADDED_SPRITE_YVEL -30
+#define TIME_ADDED_SPRITE_SHRINK_RATE 0.4
+#define TIME_ADDED_SPRITE_START_SCALE 1.2
+#define TIME_ADDED_SPRITE_MINIMUM_SCALE 0.9
+
typedef enum {
linear_move_state,
fall_state,
@@ -89,7 +98,16 @@ typedef enum {
} game_mode;
typedef struct {
+ bool active;
+ char text[TEXT_SPRITE_LENGTH];
+ SDL_FPoint position;
+
+ float scale;
+} text_sprite;
+
+typedef struct {
float time_remaining;
+ text_sprite time_added_sprites[TIMED_MODE_NUM_TIME_ADDED_SPRITES];
} timed_mode_data;
typedef struct {
@@ -439,6 +457,53 @@ void find_last_color_matching_tile_in_direction(int* sy, int* sx, int dy, int dx
}
}
+void add_time_added_sprite(float time_added, float xpos, float ypos) {
+ timed_mode_data* timed_mode_data = &game.timed_mode_data;
+
+ //If there are any inactive sprites add there
+ //if not use the oldest/most shrunk
+ int add_sprite_at = 0;
+ for (int i = 0; i < TIMED_MODE_NUM_TIME_ADDED_SPRITES; i++) {
+ if (!timed_mode_data->time_added_sprites[i].active) {
+ add_sprite_at = i;
+ break;
+ }
+
+ text_sprite* s1 = &timed_mode_data->time_added_sprites[i];
+ text_sprite* s2 = &timed_mode_data->time_added_sprites[add_sprite_at];
+
+ if (s1->scale < s2->scale)
+ add_sprite_at = i;
+ }
+
+ text_sprite* sprite = &timed_mode_data->time_added_sprites[add_sprite_at];
+ sprite->active = true;
+ snprintf(sprite->text, TEXT_SPRITE_LENGTH, "+%.2f", time_added);
+ sprite->position = (SDL_FPoint){xpos, ypos};
+ sprite->scale = TIME_ADDED_SPRITE_START_SCALE;
+}
+
+void timed_mode_process_clear(int sy, int sx, int ey, int ex) {
+ timed_mode_data* timed_mode_data = &game.timed_mode_data;
+ int tiles_cleared = SDL_abs(ey-sy) + SDL_abs(ex-sx) + 1;
+
+ float time_added = 1;
+ if (tiles_cleared > MIN_TILES_TO_CLEAR) {
+ time_added +=
+ (tiles_cleared - MIN_TILES_TO_CLEAR) * CLEAR_EXTRA_TIME_BONUS;
+ }
+
+ SDL_FPoint clear_position = board_position(sy, sx);
+ add_time_added_sprite(time_added, clear_position.x, clear_position.y);
+ timed_mode_data->time_remaining += time_added;
+}
+
+void process_clear(int sy, int sx, int ey, int ex) {
+ if (game.mode == timed_mode) {
+ timed_mode_process_clear(sy, sx, ey, ex);
+ }
+}
+
bool try_clear_at(int y, int x) {
const int axes[2][2] = {
{1, 0}, //Horizontal
@@ -455,6 +520,8 @@ bool try_clear_at(int y, int x) {
if (SDL_abs(ey-sy) + SDL_abs(ex-sx) + 1 < MIN_TILES_TO_CLEAR)
continue;
+ process_clear(sy, sx, ey, ex);
+
for (;;) {
piece_start_falling(retreive_piece(game.board[ey][ex].piece_id));
game.board[ey][ex].state = tile_currently_empty;
@@ -630,6 +697,24 @@ void draw_background(SDL_Renderer* renderer) {
}
}
+void draw_text_sprite
+(
+ SDL_Renderer* renderer,
+ sprite_font* font,
+ const text_sprite* text_sprite
+) {
+ if (!text_sprite->active)
+ return;
+
+ draw_text_with_spritefont_extended(renderer,
+ font,
+ (unsigned char*)text_sprite->text,
+ text_sprite->position.x,
+ text_sprite->position.y,
+ text_sprite->scale
+ );
+}
+
void draw_timed_mode(SDL_Renderer* renderer);
void draw_game(SDL_Renderer* renderer) {
@@ -746,6 +831,20 @@ void update_timed_mode(float dt) {
timed_mode_data->time_remaining =
SDL_max(timed_mode_data->time_remaining - dt, 0);
+
+ for (int i = 0; i < TIMED_MODE_NUM_TIME_ADDED_SPRITES; i++) {
+ text_sprite* text_sprite = &timed_mode_data->time_added_sprites[i];
+
+ if (!text_sprite->active)
+ continue;
+
+ text_sprite->position.y += TIME_ADDED_SPRITE_YVEL * dt;
+ text_sprite->scale -= TIME_ADDED_SPRITE_SHRINK_RATE * dt;
+
+ if (text_sprite->scale <= TIME_ADDED_SPRITE_MINIMUM_SCALE) {
+ text_sprite->active = false;
+ }
+ }
}
void draw_timed_mode(SDL_Renderer* renderer) {
@@ -760,6 +859,14 @@ void draw_timed_mode(SDL_Renderer* renderer) {
scale += 0.25 * SDL_sin(-timed_mode_data->time_remaining * 4);
}
+ for (int i = 0; i < TIMED_MODE_NUM_TIME_ADDED_SPRITES; i++) {
+ text_sprite* text_sprite = &timed_mode_data->time_added_sprites[i];
+
+ if (!text_sprite->active)
+ continue;
+ draw_text_sprite(renderer, &game.text_font, text_sprite);
+ }
+
draw_text_with_spritefont_extended(renderer,
&game.text_font,
(unsigned char*)timed_mode_display,