diff options
| author | Menase Teshale <osome3717@gmail.com> | 2026-09-08 08:15:47 +0300 |
|---|---|---|
| committer | Menase Teshale <osome3717@gmail.com> | 2026-09-08 08:15:47 +0300 |
| commit | 9dfdb7df2929fcfdf5f932b2e27499d3f0e5d412 (patch) | |
| tree | 08416230e1313ea39fdb5980873e88feaa64a78a | |
| parent | a03a982c026a185d617d25e6a37ce939a481e946 (diff) | |
Working on timed mode logic
| -rw-r--r-- | src/game.c | 107 |
1 files changed, 107 insertions, 0 deletions
@@ -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, |
