diff options
| -rw-r--r-- | src/game.c | 92 | ||||
| -rw-r--r-- | src/menu.c | 52 |
2 files changed, 101 insertions, 43 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); } @@ -1,10 +1,13 @@ #include "app.h" #include "font.h" +#include <stdio.h> #define MENU_ITEM_TOP_YPOS_RELATIVE 0.3 -#define MENU_ITEM_YOFFSET_RELATIVE 0.03 -#define UNSELECTED_ITEM_SCALE 1 -#define SELECTED_ITEM_SCALE 1.2 +#define MENU_ITEM_YOFFSET_RELATIVE 0.05 +#define UNSELECTED_ITEM_SCALE 2 +#define SELECTED_ITEM_SCALE 2.4 +#define MINIMUM_TIMED_MODE_TIME 5 +#define TIMED_MODE_STEP 3 typedef enum { timed_mode_option = 0, @@ -12,6 +15,7 @@ typedef enum { } menu_option; menu_option selected_option; +int timed_mode_time; sprite_font text_font; extern SDL_Window* window; @@ -25,27 +29,37 @@ void init_menu(SDL_Renderer* renderer) { } selected_option = timed_mode_option; + timed_mode_time = MINIMUM_TIMED_MODE_TIME + 2*TIMED_MODE_STEP; } void draw_menu(SDL_Renderer* renderer) { SDL_RenderClear(renderer); - const char* labels[] = { - "Timed Mode", - "Exit", - }; - float yp = MENU_ITEM_TOP_YPOS_RELATIVE; for (menu_option i = timed_mode_option; i <= exit_option; i++) { float scale = i == selected_option ? SELECTED_ITEM_SCALE : UNSELECTED_ITEM_SCALE; - draw_text_with_spritefont_extended(renderer, - &text_font, - (unsigned char*)labels[i], - get_window_relative_xpos(0.5), - get_window_relative_ypos(yp), - scale - ); + if (i == timed_mode_option) { + char timed_mode_label[100]; + snprintf(timed_mode_label, 100, "Timed Mode <%d>", timed_mode_time); + + draw_text_with_spritefont_extended(renderer, + &text_font, + (unsigned char*)timed_mode_label, + get_window_relative_xpos(0.5), + get_window_relative_ypos(yp), + scale + ); + } else if (i == exit_option) { + draw_text_with_spritefont_extended(renderer, + &text_font, + (unsigned char*)"Exit", + get_window_relative_xpos(0.5), + get_window_relative_ypos(yp), + scale + ); + } + yp += MENU_ITEM_YOFFSET_RELATIVE; } @@ -66,7 +80,7 @@ SDL_AppResult menu_execute_action() { if (selected_option == exit_option) { return SDL_APP_SUCCESS; } if (selected_option == timed_mode_option) { - init_timed_game(NULL, NULL, 5); + init_timed_game(NULL, NULL, timed_mode_time); app_state = game_state; } @@ -77,7 +91,11 @@ SDL_AppResult menu_event(SDL_Event* e) { if (e->type == SDL_EVENT_KEY_DOWN) { SDL_Scancode pressed_button = e->key.scancode; - if (pressed_button == SDL_SCANCODE_RETURN) { + if (pressed_button == SDL_SCANCODE_RIGHT && selected_option == timed_mode_option) { + timed_mode_time += TIMED_MODE_STEP; + } else if (pressed_button == SDL_SCANCODE_LEFT && selected_option == timed_mode_option) { + timed_mode_time = SDL_max(MINIMUM_TIMED_MODE_TIME, timed_mode_time-TIMED_MODE_STEP); + } else if (pressed_button == SDL_SCANCODE_RETURN) { return menu_execute_action(); } else if (pressed_button == SDL_SCANCODE_DOWN) { select_next_option(); |
