diff options
author | turnipgod | 2025-03-02 21:38:20 -0500 |
---|---|---|
committer | turnipgod | 2025-03-02 21:38:20 -0500 |
commit | 05a3b4b758fbbac9ca05d49b27c09cf2009e27fe (patch) | |
tree | 744676f2ea15573dd61217ee5bc84e8efcf5a3b6 | |
parent | 956906ac5c84c5974e7dfc10bf95a49712b9db59 (diff) |
added basic movement, line clears, flipped tetrominos on y axis
-rw-r--r-- | inc/tetromino.h | 92 | ||||
-rw-r--r-- | src/main.c | 203 |
2 files changed, 238 insertions, 57 deletions
diff --git a/inc/tetromino.h b/inc/tetromino.h index 45c335b..30d55a3 100644 --- a/inc/tetromino.h +++ b/inc/tetromino.h @@ -29,8 +29,8 @@ struct Tetromino tetrominos[7] = { .directions = { [NORTH] = { {0, 0, 0, 0}, - {1, 1, 1, 1}, {0, 0, 0, 0}, + {1, 1, 1, 1}, {0, 0, 0, 0} }, @@ -42,8 +42,8 @@ struct Tetromino tetrominos[7] = { }, [SOUTH] = { {0, 0, 0, 0}, - {0, 0, 0, 0}, {1, 1, 1, 1}, + {0, 0, 0, 0}, {0, 0, 0, 0} }, [WEST] = { @@ -59,24 +59,24 @@ struct Tetromino tetrominos[7] = { .color = BLUE, .directions = { [NORTH] = { - {1, 0, 0}, + {0, 0, 0}, {1, 1, 1}, - {0, 0, 0} + {1, 0, 0} }, [EAST] = { - {0, 1, 1}, {0, 1, 0}, - {0, 1, 0} + {0, 1, 0}, + {0, 1, 1} }, [SOUTH] = { - {0, 0, 0}, + {0, 0, 1}, {1, 1, 1}, - {0, 0, 1} + {0, 0, 0} }, [WEST] = { + {1, 1, 0}, {0, 1, 0}, - {0, 1, 0}, - {1, 1, 0} + {0, 1, 0} } } }, @@ -85,24 +85,24 @@ struct Tetromino tetrominos[7] = { .color = ORANGE, .directions = { [NORTH] = { - {0, 0, 1}, + {0, 0, 0}, {1, 1, 1}, - {0, 0, 0} + {0, 0, 1} }, [EAST] = { + {0, 1, 1}, {0, 1, 0}, - {0, 1, 0}, - {0, 1, 1} + {0, 1, 0} }, [SOUTH] = { - {0, 0, 0}, + {1, 0, 0}, {1, 1, 1}, - {1, 0, 0} + {0, 0, 0} }, [WEST] = { - {1, 1, 0}, {0, 1, 0}, - {0, 1, 0} + {0, 1, 0}, + {1, 1, 0} } } }, @@ -111,24 +111,24 @@ struct Tetromino tetrominos[7] = { .color = YELLOW, .directions = { [NORTH] = { + {0, 0, 0}, {0, 1, 1}, - {0, 1, 1}, - {0, 0, 0} + {0, 1, 1} }, [EAST] = { + {0, 0, 0}, {0, 1, 1}, - {0, 1, 1}, - {0, 0, 0} + {0, 1, 1} }, [SOUTH] = { + {0, 0, 0}, {0, 1, 1}, - {0, 1, 1}, - {0, 0, 0} + {0, 1, 1} }, [WEST] = { + {0, 0, 0}, {0, 1, 1}, - {0, 1, 1}, - {0, 0, 0} + {0, 1, 1} } } }, @@ -137,24 +137,24 @@ struct Tetromino tetrominos[7] = { .color = GREEN, .directions = { [NORTH] = { - {0, 1, 1}, + {0, 0, 0}, {1, 1, 0}, - {0, 0, 0} + {0, 1, 1} }, [EAST] = { - {0, 1, 0}, + {0, 0, 1}, {0, 1, 1}, - {0, 0, 1} + {0, 1, 0} }, [SOUTH] = { - {0, 0, 0}, + {1, 1, 0}, {0, 1, 1}, - {1, 1, 0} + {0, 0, 0} }, [WEST] = { - {1, 0, 0}, + {0, 1, 0}, {1, 1, 0}, - {0, 1, 0} + {1, 0, 0} } } }, @@ -163,9 +163,9 @@ struct Tetromino tetrominos[7] = { .color = PURPLE, .directions = { [NORTH] = { - {0, 1, 0}, + {0, 0, 0}, {1, 1, 1}, - {0, 0, 0} + {0, 1, 0} }, [EAST] = { {0, 1, 0}, @@ -173,9 +173,9 @@ struct Tetromino tetrominos[7] = { {0, 1, 0} }, [SOUTH] = { - {0, 0, 0}, + {0, 1, 0}, {1, 1, 1}, - {0, 1, 0} + {0, 0, 0} }, [WEST] = { {0, 1, 0}, @@ -189,24 +189,24 @@ struct Tetromino tetrominos[7] = { .color = RED, .directions = { [NORTH] = { - {1, 1, 0}, + {0, 0, 0}, {0, 1, 1}, - {0, 0, 0} + {1, 1, 0} }, [EAST] = { - {0, 0, 1}, + {0, 1, 0}, {0, 1, 1}, - {0, 1, 0} + {0, 0, 1} }, [SOUTH] = { - {0, 0, 0}, + {0, 1, 1}, {1, 1, 0}, - {0, 1, 1} + {0, 0, 0} }, [WEST] = { - {0, 1, 0}, + {1, 0, 0}, {1, 1, 0}, - {1, 0, 0} + {0, 1, 0} } } } diff --git a/src/main.c b/src/main.c index 0b65f7d..35cb460 100644 --- a/src/main.c +++ b/src/main.c @@ -11,7 +11,7 @@ #define BLOCK_SIZE 25 -#define FALL_TICK 0.5 +#define FALL_TICK 0.2 enum Phases { GENERATION, @@ -35,9 +35,9 @@ struct { } current_piece; struct Color matrix[MATRIX_WIDTH][MATRIX_HEIGHT]; -int piece_queue[2][TETROMINO_COUNT] = { - {0, 1, 2, 3, 4, 5, 6}, - {0, 1, 2, 3, 4, 5, 6} +int piece_queue[TETROMINO_COUNT*2] = { + 0, 1, 2, 3, 4, 5, 6, + 0, 1, 2, 3, 4, 5, 6 }; int current_bag = 0; int current_piece_index = 0; @@ -80,7 +80,7 @@ void render_matrix(void) if (tetrominos[current_piece.type].directions[current_piece.rotation][j][i] == 1) { draw_block( (matrix_origin_x + ((current_piece.pos_x + i - 1) * BLOCK_SIZE)) + 1 - ,(matrix_origin_y + ((current_piece.pos_y - j + 1) * BLOCK_SIZE)) + 1 + ,(matrix_origin_y + ((current_piece.pos_y + j - 1) * BLOCK_SIZE)) + 1 ,BLOCK_SIZE - 2 ,BLOCK_SIZE - 2 ,tetrominos[current_piece.type].color @@ -100,27 +100,195 @@ void shuffle_bag(int *bag) } } +int is_overlap(int x, int y) +{ + for (int i = 0; i < tetrominos[current_piece.type].size; i++) { + for (int j = 0; j < tetrominos[current_piece.type].size; j++) { + if (tetrominos[current_piece.type].directions[current_piece.rotation][j][i] == 1) { + if (current_piece.pos_x + i - 1 + x >= MATRIX_WIDTH + || current_piece.pos_x + i - 1 + x < 0 + || current_piece.pos_y + j - 1 + y < 0 + || (!ColorIsEqual(BLACK, matrix[current_piece.pos_x + i - 1 + x][current_piece.pos_y + j - 1 + y]) + && !ColorIsEqual(WHITE, matrix[current_piece.pos_x + i - 1 + x][current_piece.pos_y + j - 1 + y]))) { + return 1; + } + } + } + } + return 0; +} + void generation_phase(void) { // bag generation - if (current_piece_index > TETROMINO_COUNT) { + if (current_piece_index == 14) { + shuffle_bag(&(piece_queue[7])); current_piece_index = 0; - shuffle_bag(piece_queue[current_bag]); - current_bag = !current_bag; + } + if (current_piece_index == 7) { + shuffle_bag(piece_queue); } // set current piece - current_piece.type = piece_queue[current_bag][current_piece_index++]; + current_piece.type = piece_queue[current_piece_index++]; current_piece.rotation = NORTH; current_piece.pos_x = 4; current_piece.pos_y = 20; + if (is_overlap(0,0)) { + CloseWindow(); + } +} + +void handle_rotate(void) +{ + static int rotated_cw = 0; + static int rotated_ccw = 0; + if (game_phase == FALL || game_phase == LOCK) { + if (IsKeyDown(KEY_L) && !rotated_cw) { + current_piece.rotation++; + current_piece.rotation = current_piece.rotation % 4; + if (is_overlap(0, 0)) { + current_piece.rotation--; + if (current_piece.rotation < 0) current_piece.rotation = 3; + } + rotated_cw = 1; + } + if (IsKeyUp(KEY_L)) { + rotated_cw = 0; + } + if (IsKeyDown(KEY_J) && !rotated_ccw) { + current_piece.rotation--; + if (current_piece.rotation < 0) current_piece.rotation = 3; + if (is_overlap(0, 0)) { + current_piece.rotation++; + current_piece.rotation = current_piece.rotation % 4; + } + rotated_ccw = 1; + } + if (IsKeyUp(KEY_J)) { + rotated_ccw = 0; + } + } +} + +void move_right(void) +{ + if (is_overlap(1, 0)) { + return; + } + current_piece.pos_x++; +} + +void move_left(void) +{ + if (is_overlap(-1, 0)) { + return; + } + current_piece.pos_x--; +} + +void handle_lr(void) +{ + static int moved_right = 0; + static int moved_left = 0; + if (game_phase == FALL || game_phase == LOCK) { + if (IsKeyDown(KEY_D) && !moved_right) { + move_right(); + moved_right = 1; + } + if (IsKeyUp(KEY_D)) { + moved_right = 0; + } + if (IsKeyDown(KEY_A) && !moved_left) { + move_left(); + moved_left = 1; + } + if (IsKeyUp(KEY_A)) { + moved_left = 0; + } + } +} + +void move_piece_to_matrix(void) +{ + for (int i = 0; i < tetrominos[current_piece.type].size; i++) { + for (int j = 0; j < tetrominos[current_piece.type].size; j++) { + if (tetrominos[current_piece.type].directions[current_piece.rotation][j][i] == 1) { + matrix[current_piece.pos_x + i - 1][current_piece.pos_y + j - 1] = tetrominos[current_piece.type].color; + } + } + } +} + +void handle_fall(void) +{ + static double phase_time = 0.0; + if (game_phase == FALL) { + phase_time += GetFrameTime(); + if ((!IsKeyDown(KEY_S) && phase_time < FALL_TICK) || phase_time < FALL_TICK * 0.5) { + return; + } else { + phase_time = 0.0; + } + } + + if (is_overlap(0, -1)) { + move_piece_to_matrix(); + generation_phase(); + return; + } + + current_piece.pos_y--; +} + +void handle_hard_drop(void) +{ + static int dropped = 0; + if (game_phase == FALL) { + if (IsKeyDown(KEY_W) && !dropped) { + dropped = 1; + while(!is_overlap(0, -1)) { + current_piece.pos_y--; + } + } + if (IsKeyUp(KEY_W)) { + dropped = 0; + } + } +} + +void clear_line(int line) { + for (int y = line; y < MATRIX_HEIGHT - 1; y++) { + for (int x = 0; x < MATRIX_WIDTH; x++) { + matrix[x][y] = matrix[x][y+1]; + if (ColorIsEqual(matrix[x][y], WHITE) && y < 20) { + matrix[x][y] = BLACK; + } + } + } +} + +void handle_line_clears(void) +{ + for (int y = 0; y < MATRIX_HEIGHT; y++) { + int line_full = 1; + for (int x = 0; x < MATRIX_WIDTH; x++) { + if (ColorIsEqual(matrix[x][y], BLACK) || ColorIsEqual(matrix[x][y], WHITE)) { + line_full = 0; + } + } + if (line_full) { + clear_line(y); + } + } } int main(void) { - //srand(time(NULL)); + srand(time(NULL)); InitWindow(SCREEN_WIDTH, SCREEN_HEIGHT, "~turnipGod's Tetris"); + // set all blocks to white for (int y = 0; y < 40; y++) { for (int x = 0; x < 10; x++) { @@ -128,9 +296,22 @@ int main(void) } } - shuffle_bag(piece_queue[0]); + for (int y = 0; y < 20; y++) { + for (int x = 0; x < 10; x++) { + matrix[x][y] = BLACK; + } + } + + game_phase = FALL; + shuffle_bag(piece_queue); + shuffle_bag(&(piece_queue[7])); generation_phase(); while (!WindowShouldClose()) { + handle_lr(); + handle_rotate(); + handle_hard_drop(); + handle_fall(); + handle_line_clears(); BeginDrawing(); ClearBackground(WHITE); render_matrix(); |