diff options
Diffstat (limited to 'src/game.c')
| -rw-r--r-- | src/game.c | 92 |
1 files changed, 66 insertions, 26 deletions
@@ -92,6 +92,7 @@ typedef enum { neutral_state, piece_held_state, swap_animation_state, + cascade_state, game_over_state } game_scene_state; @@ -443,27 +444,6 @@ void update_intro_state() { game.state = neutral_state; } -static inline void find_piece_on_board -( - int piece_id, - int* board_y_pos, - int* board_x_pos - ) { - *board_y_pos = -1; - *board_x_pos = -1; - - for (int i = 0; i < game.board_height; i++) { - for (int j = 0; j < game.board_width; j++) { - if (filled_tile_at(i, j) && game.board[i][j].piece_id == piece_id) { - *board_y_pos = i; - *board_x_pos = j; - - return; - } - } - } -} - void find_last_color_matching_tile_in_direction(int* sy, int* sx, int dy, int dx) { if (!filled_tile_at(*sy, *sx)) return; @@ -534,6 +514,12 @@ void process_clear(int sy, int sx, int ey, int ex) { } } + +static inline void play_sound_effect(MIX_Audio* audio) { + MIX_SetTrackAudio(game.effect_track, audio); + MIX_PlayTrack(game.effect_track, 0); +} + bool try_clear_at(int y, int x) { const int axes[2][2] = { {1, 0}, //Horizontal @@ -562,12 +548,25 @@ bool try_clear_at(int y, int x) { ey += dy; ex += dx; } + play_sound_effect(game.pop_audio); return true; } return false; } +bool cascade_followup() { + bool tiles_cleared = false; + + for (int i = game.board_height; i >= 0; i--) { + for (int j = game.board_width; j >= 0; j--) { + tiles_cleared |= try_clear_at(i, j); + } + } + + return tiles_cleared; +} + void cascade_tiles() { for (int j = 0; j < game.board_width; j++) { for (int i = 0; i < game.board_height; i++) { @@ -591,9 +590,46 @@ void cascade_tiles() { } } -static inline void play_sound_effect(MIX_Audio* audio) { - MIX_SetTrackAudio(game.effect_track, audio); - MIX_PlayTrack(game.effect_track, 0); +void update_cascade_state() { + if (game.state != cascade_state) + return; + + for (int i = 0; i < game.num_pieces; i++) { + if (game.pieces[i].state != static_state && game.pieces[i].state != fall_state) { + return; + } + } + + bool extra_tiles_cleared = cascade_followup(); + + if (extra_tiles_cleared) { + cascade_tiles(); + game.state = cascade_state; + } else { + game.state = neutral_state; + } +} + + +static inline void find_piece_on_board +( + int piece_id, + int* board_y_pos, + int* board_x_pos + ) { + *board_y_pos = -1; + *board_x_pos = -1; + + for (int i = 0; i < game.board_height; i++) { + for (int j = 0; j < game.board_width; j++) { + if (filled_tile_at(i, j) && game.board[i][j].piece_id == piece_id) { + *board_y_pos = i; + *board_x_pos = j; + + return; + } + } + } } void update_piece_swap_animation_state() { @@ -621,7 +657,7 @@ void update_piece_swap_animation_state() { if (tiles_cleared) { play_sound_effect(game.pop_audio); cascade_tiles(); - game.state = intro_state; + game.state = cascade_state; return; } } @@ -681,6 +717,7 @@ void update_game(float dt) { scroll_background(dt); update_intro_state(); + update_cascade_state(); update_piece_swap_animation_state(); update_timed_mode(dt); @@ -955,7 +992,10 @@ void game_event(SDL_Event* e) { void update_timed_mode(float dt) { timed_mode_data* timed_mode_data = &game.timed_mode_data; - if (game.state != intro_state && game.state != swap_animation_state) { + if (game.state != intro_state && + game.state != swap_animation_state + && game.state != cascade_state + ) { timed_mode_data->time_remaining = SDL_max(timed_mode_data->time_remaining - dt, 0); } |
