summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorMenase Teshale <osome3717@gmail.com>2026-08-20 00:48:11 +0300
committerMenase Teshale <osome3717@gmail.com>2026-08-20 00:48:11 +0300
commit7ddea7173d0e743e10329171ba9f796f74fb5fb9 (patch)
tree5d7c91f14b20a79234d355eb54dfbbcdec83f908 /src
parentbe5479e73c1c338cd369ddd99d19563c7349cda6 (diff)
Added a a delay to swap effects resolving
- Now swapping pieces will store what was swapped and put you in a swap state - All effects are resolved after swapping animations are completed
Diffstat (limited to 'src')
-rw-r--r--src/game.c219
1 files changed, 134 insertions, 85 deletions
diff --git a/src/game.c b/src/game.c
index 9c4d22e..b85d3ca 100644
--- a/src/game.c
+++ b/src/game.c
@@ -72,7 +72,8 @@ typedef struct {
typedef enum {
intro_state,
neutral_state,
- piece_held_state
+ piece_held_state,
+ swap_animation_state
} game_scene_state;
typedef struct {
@@ -88,6 +89,7 @@ typedef struct {
int board_height;
int selected_piece_id;
+ int swap_piece_id;
SDL_Texture* background_texture;
float background_offset;
@@ -323,6 +325,132 @@ 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;
+
+ piece* start_piece = retreive_piece(game.board[*sy][*sx].piece_id);
+
+ for(;;) {
+ int ny = *sy + dy, nx = *sx + dx;
+
+ if (!filled_tile_at(ny, nx))
+ return;
+
+ piece* next_piece = retreive_piece(game.board[ny][nx].piece_id);
+
+ if (!next_piece || next_piece->piece_color != start_piece->piece_color)
+ return;
+
+ *sy = ny; *sx = nx;
+ }
+}
+
+bool try_clear_at(int y, int x) {
+ const int axes[2][2] = {
+ {1, 0}, //Horizontal
+ {0, 1} //Vertical
+ };
+
+ for (int a = 0; a < 2; a++) {
+ int sy = y, sx = x, dy = axes[a][1], dx = axes[a][0];
+ find_last_color_matching_tile_in_direction(&sy, &sx, dy, dx);
+
+ int ey = sy, ex = sx;
+ find_last_color_matching_tile_in_direction(&ey, &ex, -dy, -dx);
+
+ if (SDL_abs(ey-sy) + SDL_abs(ex-sx) + 1 < MIN_TILES_TO_CLEAR)
+ continue;
+
+ for (;;) {
+ piece_start_falling(retreive_piece(game.board[ey][ex].piece_id));
+ game.board[ey][ex].state = tile_currently_empty;
+
+ if (ey == sy && ex == sx)
+ break;
+
+ ey += dy; ex += dx;
+ }
+
+ return true;
+ }
+
+ return false;
+}
+
+void cascade_tiles() {
+ for (int j = 0; j < game.board_width; j++) {
+ for (int i = 0; i < game.board_height; i++) {
+ if (game.board[i][j].state != tile_currently_empty)
+ continue;
+
+ //Look for the first filled tile above and start moving it down
+ for (int c = i-1; c >= 0; c--) {
+ if (game.board[c][j].state == tile_filled) {
+ piece* piece = retreive_piece(game.board[c][j].piece_id);
+ piece_start_moving_to(piece,
+ board_position(c+1, j),
+ PIECE_LINEAR_SPEED
+ );
+ game.board[c+1][j] = game.board[c][j];
+ }
+ }
+
+ add_piece_at(0, j);
+ }
+ }
+}
+
+void update_piece_swap_animation_state() {
+ for (int i = 0; i < game.num_pieces; i++) {
+ if (game.pieces[i].state != static_state && game.pieces[i].state != fall_state)
+ return;
+ }
+
+ int selected_piece_id = game.selected_piece_id;
+ int swap_piece_id = game.swap_piece_id;
+
+ int selected_y, selected_x;
+ int swap_y, swap_x;
+
+ find_piece_on_board(selected_piece_id, &selected_y, &selected_x);
+ find_piece_on_board(swap_piece_id, &swap_y, &swap_x);
+
+ if (filled_tile_at(selected_y, selected_x) && filled_tile_at(swap_y, swap_x)) {
+ bool tiles_cleared = try_clear_at(selected_y, selected_x);
+ tiles_cleared = try_clear_at(swap_y, swap_x) || tiles_cleared;
+
+ if (tiles_cleared) {
+ cascade_tiles();
+ game.state = intro_state;
+ return;
+ }
+ }
+
+ game.state = neutral_state;
+}
+
void handle_piece_rotation(float dt) {
int selected_piece_id = mouse_on_piece();
@@ -367,6 +495,8 @@ void update_game(float dt) {
if (game.state == intro_state) {
update_intro_state();
+ } else if (game.state == swap_animation_state) {
+ update_piece_swap_animation_state();
}
}
@@ -460,82 +590,6 @@ void swap_pieces_at(int x1, int y1, int x2 , int y2) {
}
}
-void find_last_color_matching_tile_in_direction(int* sy, int* sx, int dy, int dx) {
- if (!filled_tile_at(*sy, *sx))
- return;
-
- piece* start_piece = retreive_piece(game.board[*sy][*sx].piece_id);
-
- for(;;) {
- int ny = *sy + dy, nx = *sx + dx;
-
- if (!filled_tile_at(ny, nx))
- return;
-
- piece* next_piece = retreive_piece(game.board[ny][nx].piece_id);
-
- if (!next_piece || next_piece->piece_color != start_piece->piece_color)
- return;
-
- *sy = ny; *sx = nx;
- }
-}
-
-bool try_clear_at(int y, int x) {
- const int axes[2][2] = {
- {1, 0}, //Horizontal
- {0, 1} //Vertical
- };
-
- for (int a = 0; a < 2; a++) {
- int sy = y, sx = x, dy = axes[a][1], dx = axes[a][0];
- find_last_color_matching_tile_in_direction(&sy, &sx, dy, dx);
-
- int ey = sy, ex = sx;
- find_last_color_matching_tile_in_direction(&ey, &ex, -dy, -dx);
-
- if (SDL_abs(ey-sy) + SDL_abs(ex-sx) + 1 < MIN_TILES_TO_CLEAR)
- continue;
-
- for (;;) {
- piece_start_falling(retreive_piece(game.board[ey][ex].piece_id));
- game.board[ey][ex].state = tile_currently_empty;
-
- if (ey == sy && ex == sx)
- break;
-
- ey += dy; ex += dx;
- }
-
- return true;
- }
-
- return false;
-}
-
-void cascade_pieces() {
- for (int j = 0; j < game.board_width; j++) {
- for (int i = 0; i < game.board_height; i++) {
- if (game.board[i][j].state != tile_currently_empty)
- continue;
-
- //Look for the first filled tile above and start moving it down
- for (int c = i-1; c >= 0; c--) {
- if (game.board[c][j].state == tile_filled) {
- piece* piece = retreive_piece(game.board[c][j].piece_id);
- piece_start_moving_to(piece,
- board_position(c+1, j),
- PIECE_LINEAR_SPEED
- );
- game.board[c+1][j] = game.board[c][j];
- }
- }
-
- add_piece_at(0, j);
- }
- }
-}
-
void piece_held_event(SDL_Event* e) {
if (e->type == SDL_EVENT_MOUSE_BUTTON_UP && e->button.button == SDL_BUTTON_LEFT) {
int swap_piece_id = mouse_on_piece();
@@ -568,15 +622,10 @@ void piece_held_event(SDL_Event* e) {
}
swap_pieces_at(selected_x, selected_y, swap_x, swap_y);
+ game.swap_piece_id = swap_piece_id;
- bool tiles_cleared = try_clear_at(selected_y, selected_x);
- tiles_cleared = try_clear_at(swap_y, swap_x) || tiles_cleared; //sneaky short circuit glitch
-
- if (tiles_cleared) {
- cascade_pieces();
- game.state = intro_state;
- return;
- }
+ game.state = swap_animation_state;
+ return;
}
game.state = neutral_state;