diff options
| author | Abdellah El Morabit <nsrddyn@gmail.com> | 2025-01-17 21:42:02 +0100 |
|---|---|---|
| committer | Abdellah El Morabit <nsrddyn@gmail.com> | 2025-01-17 21:42:02 +0100 |
| commit | 9ff91999b122df64c910b3d7ebed1ceda949e0c0 (patch) | |
| tree | e7c91ec9af16f850057238657d495938df3e2158 /TETRIS.c | |
| parent | de3d3056c8b82d868ff42362a2f6e9d2cd26a551 (diff) | |
collision works but overlaps
Diffstat (limited to 'TETRIS.c')
| -rw-r--r-- | TETRIS.c | 307 |
1 files changed, 206 insertions, 101 deletions
@@ -1,27 +1,53 @@ +/* + * ===================================================================================== + * + * Filename: Tetris.c + * + * Description: Tetris in raylib + * + * Version: 1.0 + * Created: 01/17/2025 09:58:53 + * Revision: 1.0 + * Compiler: gcc + * + * Author: nsrddyn, + * Organization: + * + * ===================================================================================== + */ + #include <raylib.h> #include <stdlib.h> #include <stdio.h> #include <time.h> // GAME SETTINGS -#define FPS 30 -#define FONT_SIZE 20 +#define FPS 60 +#define FONT_SIZE 10 -#define TETROMINO_SIZE 4 +#define TETROMINO_SIZE_HEIGHT 2 +#define TETROMINO_SIZE_WIDTH 4 -#define CYAN_I (Color) { 0, 255, 255, 255 } -#define YELLOW_O (Color) { 255, 255, 102, 255 } -#define PURPLE_T (Color) { 138, 43, 226, 255 } -#define GREEN_S (Color) { 34, 139, 34, 255 } -#define RED_Z (Color) { 255, 69, 0, 255 } -#define BLUE_J (Color) { 70, 130, 180, 255 } -#define ORANGE_L (Color) { 255, 140, 0, 255 } +#define CYAN_I \ + (Color) { 0, 255, 255, 255 } +#define YELLOW_O \ + (Color) { 255, 255, 102, 255 } +#define PURPLE_T \ + (Color) { 138, 43, 226, 255 } +#define GREEN_S \ + (Color) { 34, 139, 34, 255 } +#define RED_Z \ + (Color) { 255, 69, 0, 255 } +#define BLUE_J \ + (Color) { 70, 130, 180, 255 } +#define ORANGE_L \ + (Color) { 255, 140, 0, 255 } // Window and Grid Settings -static const int SCREEN_WIDTH = 400; -static const int SCREEN_HEIGHT = 600; -static const int COLUMNS = 10; -static const int ROWS = 20; +static const int SCREEN_WIDTH = 400; +static const int SCREEN_HEIGHT = 600; +static const int COLUMNS = 10; // Default standardized value for the amount of COLUMNS +static const int ROWS = 20; // Default standardized value for the amount of ROWS static const int CELL_WIDTH = SCREEN_WIDTH / COLUMNS; static const int CELL_HEIGHT = SCREEN_HEIGHT / ROWS; @@ -29,10 +55,10 @@ static int SCORE = 0; typedef struct { - int blocks[TETROMINO_SIZE][TETROMINO_SIZE]; + int blocks[TETROMINO_SIZE_HEIGHT][TETROMINO_SIZE_WIDTH]; Color color; - int x; - int y; + int x; + int y; } TETROMINO; @@ -42,55 +68,76 @@ TETROMINO TETROMINOES[7] = { { {0, 0, 0, 0}, {1, 1, 1, 1}, - {0, 0, 0, 0}, - {0, 0, 0, 0}}, - CYAN_I, 0, 0}, + }, + CYAN_I, + COLUMNS / 2, + 0}, + // supposed to have 2 forms of rotations + // default spawn location is: center { { {0, 1, 1, 0}, {0, 1, 1, 0}, - {0, 0, 0, 0}, - {0, 0, 0, 0}}, - YELLOW_O, 0, 0}, + }, + YELLOW_O, + COLUMNS / 2, + 0}, + // supposed to have no rotation forms + // default spawn location is: center { { {0, 1, 0, 0}, {1, 1, 1, 0}, - {0, 0, 0, 0}, - {0, 0, 0, 0}}, - PURPLE_T, 0, 0}, + }, + PURPLE_T, + 0, + 0}, + // flat side left center + // 4 rotational forms { { {0, 1, 1, 0}, {1, 1, 0, 0}, - {0, 0, 0, 0}, - {0, 0, 0, 0}}, - GREEN_S, 0, 0}, + }, + GREEN_S, + 0, + 0}, + // left center + // 4 rotational forms { { {1, 1, 0, 0}, {0, 1, 1, 0}, - {0, 0, 0, 0}, - {0, 0, 0, 0}}, - RED_Z, 0, 0}, + }, + RED_Z, + 0, + 0}, + // left center + // 4 rotational forms { { {1, 0, 0, 0}, {1, 1, 1, 0}, - {0, 0, 0, 0}, - {0, 0, 0, 0}}, - BLUE_J, 0, 0}, + }, + BLUE_J, + 0, + 0}, + // flat side first and left center + // 4 rotational forms { { {0, 0, 1, 0}, {1, 1, 1, 0}, - {0, 0, 0, 0}, - {0, 0, 0, 0}}, - ORANGE_L, 0, 0}, + }, + ORANGE_L, + 0, + 0}, + // flat side first and left center + // 4 rotational forms }; -void DRAW_GRID_BACKGROUND() +void DRAW_BACKGROUND_GRID() { for (int i = 0; i <= COLUMNS; i++) { @@ -109,6 +156,7 @@ int **CREATE_TETROMINOS_GRID(int rows, int columns) return NULL; for (int i = 0; i < rows; i++) + { array[i] = calloc(columns, sizeof(int)); if (!array[i]) @@ -122,32 +170,95 @@ int **CREATE_TETROMINOS_GRID(int rows, int columns) return array; } -// detect if the active tetromino is hitting another tetromino -int COLLISION_DETECTION(TETROMINO *ACTIVE_TETROMINO, int **GRID) +void CHECK_FULL_LINE(int **GRID) { - for (int y = 0; y < TETROMINO_SIZE; y++) { - for (int x = 0; x < TETROMINO_SIZE; x++) { - if (ACTIVE_TETROMINO->blocks[y][x] == 1) { - int GRID_X = ACTIVE_TETROMINO->x + x; - int GRID_Y = ACTIVE_TETROMINO->y + y; + for (int y = 0; y < ROWS; y++) + { + bool FULL_LINE = true; - if (GRID_X < 0 || GRID_X >= COLUMNS || GRID_Y >= ROWS) { - // COLLISION - return 1; - } + for (int x = 0; x < COLUMNS; x++) + { + if (GRID[y][x] == 0) + { + FULL_LINE = false; + break; + } + } - if (GRID_X >= 0 && GRID[GRID_Y][GRID_X] == 1) { - // COLLISION - return 1; - } + if (FULL_LINE) + { + for (int i = y; i > 0; i--) + { + for (int x = 0; x < COLUMNS; x++) + GRID[i][x] = GRID[i - 1][x]; } + + for (int x = 0; x < COLUMNS; x++) + GRID[ROWS - 2][x] = 0; + + SCORE += 10; } } +} + + + +// Detect if the active tetromino is hitting another tetromino +int COLLISION_DETECTION(TETROMINO *tetromino, int **GRID) +{ + + // FIND THE WIDTH AND HEIGHT OF THE ACTIVE TETROMINO + + int CURRENT_LOWEST_INDEX_X = 0; + int CURRENT_LOWEST_INDEX_Y = 0; + + for (int y = 0; y < TETROMINO_SIZE_HEIGHT; y++) + { + for (int x = 0; x < TETROMINO_SIZE_WIDTH; x++) + { + if (tetromino->blocks[y][x] == 1) + { + CURRENT_LOWEST_INDEX_X = x; + CURRENT_LOWEST_INDEX_Y = y; + } + } + } + + for (int i = 0; i < TETROMINO_SIZE_HEIGHT; i++) + { + for (int j = 0; j < TETROMINO_SIZE_WIDTH; j++) + { + if (tetromino->blocks[i][j] == 1) + { + int GRID_X = tetromino->x + j; + int GRID_Y = tetromino->y + i; + + + // BLOCKS COLLISION + if (GRID_Y > 0 && GRID[GRID_Y][GRID_X] != 0) + return 1; + } + } + } // NO COLLISION return 0; } +int *ROTATE_ACTIVE_TETROMINO(TETROMINO *tetromino, int **GRID) +{ + int *ROTATED_TETROMINO; + + for (int x = 0; x < COLUMNS; x++) + { + for (int y = 0; y < ROWS; y++) + { + ROTATED_TETROMINO = 0; + } + } + return ROTATED_TETROMINO; +} + void FREE_GRID(int **array, int rows) { for (int i = 0; i < rows; i++) @@ -157,17 +268,17 @@ void FREE_GRID(int **array, int rows) void DRAW_TETROMINO(TETROMINO *tetromino) { - for (int y = 0; y < TETROMINO_SIZE; y++) + for (int y = 0; y < TETROMINO_SIZE_HEIGHT; y++) { - for (int x = 0; x < TETROMINO_SIZE; x++) + for (int x = 0; x < TETROMINO_SIZE_WIDTH; x++) { if (tetromino->blocks[y][x] == 1) { DrawRectangle( - (tetromino->x + x) * CELL_WIDTH, - (tetromino->y + y) * CELL_HEIGHT, - CELL_WIDTH, CELL_HEIGHT, - tetromino->color); + (tetromino->x + x) * CELL_WIDTH, + (tetromino->y + y) * CELL_HEIGHT, + CELL_WIDTH, CELL_HEIGHT, + tetromino->color); } } } @@ -177,29 +288,33 @@ TETROMINO SPAWN_TETROMINO() { int RANDOM_INDEX = GetRandomValue(0, 6); TETROMINO tetromino = TETROMINOES[RANDOM_INDEX]; - tetromino.x = COLUMNS / 2 - 2; - tetromino.y = 0; + + if (tetromino.x == 0) + { + tetromino.x = COLUMNS / 2 - 2; + tetromino.y = 0; + } return tetromino; } void MOVE_TETROMINO(TETROMINO *tetromino, int **GRID) { - if (!IsKeyDown(KEY_LEFT_SHIFT) && COLLISION_DETECTION(tetromino, GRID) == 0) - { - if (IsKeyDown(KEY_RIGHT) && tetromino->x + TETROMINO_SIZE < COLUMNS) - tetromino->x++; - if (IsKeyDown(KEY_LEFT) && tetromino->x > 0) - tetromino->x--; - if (IsKeyDown(KEY_DOWN) && tetromino->y < ROWS - 2 ) - tetromino->y++; - } + // RIGHT WALL COLLISION DETECTION BY STOPPING MOVEMENT + if (IsKeyDown(KEY_RIGHT) && COLLISION_DETECTION(tetromino, GRID) == 0 && tetromino->x < COLUMNS - 2) + tetromino->x++; + // LEFT WALL COLLISION DETECTION BY STOPPING MOVEMENT + if (IsKeyDown(KEY_LEFT) && COLLISION_DETECTION(tetromino, GRID) == 0 && tetromino->x > 0) + tetromino->x--; + // BOTTOM ROW COLLISION DETECTION BY STOPPING MOVEMENT + if (IsKeyDown(KEY_DOWN) && COLLISION_DETECTION(tetromino, GRID) == 0 && tetromino->y < ROWS - 2) + tetromino->y++; } void SAVE_TETROMINO(TETROMINO *tetromino, int **GRID) { - for (int y = 0; y < TETROMINO_SIZE; y++) + for (int y = 0; y < TETROMINO_SIZE_HEIGHT; y++) { - for (int x = 0; x < TETROMINO_SIZE; x++) + for (int x = 0; x < TETROMINO_SIZE_WIDTH; x++) { if (tetromino->blocks[y][x] == 1) { @@ -219,7 +334,7 @@ void DRAW_SAVED_TETROMINO(int **GRID, TETROMINO *tetromino) for (int x = 0; x < COLUMNS; x++) { if (GRID[y][x] == 1) - DrawRectangle((x * CELL_WIDTH) , (y * CELL_HEIGHT) , CELL_WIDTH, CELL_HEIGHT, tetromino->color); + DrawRectangle((x * CELL_WIDTH), (y * CELL_HEIGHT), CELL_WIDTH, CELL_HEIGHT, tetromino->color); } } } @@ -230,44 +345,34 @@ void DRAW_STATS(TETROMINO *tetromino) sprintf(SCORE_TEXT, "SCORE: %d", SCORE); DrawText(SCORE_TEXT, 10, 10, FONT_SIZE, BLUE); - char CURRENT_Y_POSITION[16], CURRENT_X_POSITION[16]; - sprintf(CURRENT_Y_POSITION, "Y: %d", tetromino->y); - sprintf(CURRENT_X_POSITION, "X: %d", tetromino->x); - DrawText(CURRENT_Y_POSITION, 10, 30, FONT_SIZE, BLUE); - DrawText(CURRENT_X_POSITION, 10, 50, FONT_SIZE, BLUE); -} + char CURRENT_Y_POSITION[32], CURRENT_X_POSITION[32]; + sprintf(CURRENT_Y_POSITION, "Y COÖRDINATE: %d", tetromino->y); + sprintf(CURRENT_X_POSITION, "X COÖRDINATE: %d", tetromino->x); + DrawText(CURRENT_Y_POSITION, 10, 50, FONT_SIZE, BLUE); + DrawText(CURRENT_X_POSITION, 10, 80, FONT_SIZE, BLUE); -void CHECK_FULL_LINE(int **GRID) -{ - int LAST_LINE_Y = ROWS - 2; - bool FULL_LINE = true; + int POS_X = SCREEN_WIDTH / 2; + int POS_Y = SCREEN_HEIGHT / 2; - for (int x = 0; x <= COLUMNS; x++) - { - if (GRID[LAST_LINE_Y][x] == 0) - { - FULL_LINE = false; - } - - } - if (!FULL_LINE){ - for (int x = 0; x <= COLUMNS; x++) - { - GRID[LAST_LINE_Y][x] = GRID[LAST_LINE_Y][0]; - } - } + const char ERROR_TEXT[] = "LOW FPS"; + if (GetFPS() < 40) + DrawText(ERROR_TEXT, POS_X, POS_Y, FONT_SIZE, RED); } int main() { + // Initialize the window and set the wanted FPS InitWindow(SCREEN_WIDTH, SCREEN_HEIGHT, "Tetris"); SetTargetFPS(FPS); + + // Spawn a new tetromino TETROMINO ACTIVE_TETROMINO = SPAWN_TETROMINO(); + int **GRID = CREATE_TETROMINOS_GRID(ROWS, COLUMNS); if (!GRID) { - printf("FAILED TO ALLOCATE MEMORY FOR THE GRID"); + printf("Failed to allocate memory for the grid."); CloseWindow(); return 1; } @@ -277,14 +382,14 @@ int main() BeginDrawing(); ClearBackground(BLACK); - DRAW_GRID_BACKGROUND(); + DRAW_BACKGROUND_GRID(); DRAW_SAVED_TETROMINO(GRID, &ACTIVE_TETROMINO); DRAW_TETROMINO(&ACTIVE_TETROMINO); DRAW_STATS(&ACTIVE_TETROMINO); MOVE_TETROMINO(&ACTIVE_TETROMINO, GRID); - if (ACTIVE_TETROMINO.y == ROWS - 2 && COLLISION_DETECTION(&ACTIVE_TETROMINO,GRID) == 0) + if (ACTIVE_TETROMINO.y == ROWS - 2 || COLLISION_DETECTION(&ACTIVE_TETROMINO, GRID) != 0) { SCORE++; SAVE_TETROMINO(&ACTIVE_TETROMINO, GRID); |
