#include #include #include #include "raylib.h" /* * each cube is 1 unit, so FACT is used as a scale factor for the size of the * screen */ #define WIDTH 10 #define HEIGHT 22 #define VIS_HEIGHT 20 #define FACT 40 /* since the game only moves on a block per block basis, no smoothness is * necessary, so the only thing FPS controls is how fast the blocks move left * and right, due to how often it polls */ #define FPS 30 #define CYAN CLITERAL(Color){ 0, 255, 255, 255 } typedef struct Vector2Int { int x, y; } Vector2Int; typedef struct Tetromino { Color colour; Vector2Int pos[4]; // position of 4 cubes making the tetromino } Tetromino; void Draw2DGrid(Color grid[WIDTH][HEIGHT]); int main(void){ int const width = WIDTH * FACT, height = HEIGHT * FACT, vis_height = VIS_HEIGHT * FACT; Color grid[WIDTH][HEIGHT]; // if colour is WHITE, the position is empty int interval = FPS, count, i, j; Tetromino cur_trmno; // trnmo is faster and easier to write than tetromino bool gen_trmno = true; srand(time(NULL)); for (i = 0; i < WIDTH; i++) for (j = 0; j < HEIGHT; j++) grid[i][j] = WHITE; InitWindow(width, height, "retris"); SetTargetFPS(FPS); for (count = 0; !WindowShouldClose(); count++) { if (gen_trmno) { switch (rand() % 1) { case 0: cur_trmno.colour = CYAN; for (i = 0; i < 4; i++) { cur_trmno.pos[i].x = WIDTH / 2; // 3 - i so that tetrominoes are listed from bottom up; if drawn // from top to bottom on line 69, then they will overlap and just // be 1 cube cur_trmno.pos[i].y = 3 - i; grid[cur_trmno.pos[i].x][cur_trmno.pos[i].y] = cur_trmno.colour; } } gen_trmno = false; } if (count >= (IsKeyDown(KEY_DOWN) ? FPS/30 : interval)) { count = 0; for (i = 0; i < 4; i++) { grid[cur_trmno.pos[i].x][cur_trmno.pos[i].y] = WHITE; cur_trmno.pos[i].y++; grid[cur_trmno.pos[i].x][cur_trmno.pos[i].y] = cur_trmno.colour; } } if (IsKeyDown(KEY_RIGHT)) { for (i = 0; i < 4; i++) { grid[cur_trmno.pos[i].x][cur_trmno.pos[i].y] = WHITE; cur_trmno.pos[i].x++; grid[cur_trmno.pos[i].x][cur_trmno.pos[i].y] = cur_trmno.colour; } } else if (IsKeyDown(KEY_LEFT)) { for (i = 0; i < 4; i++) { grid[cur_trmno.pos[i].x][cur_trmno.pos[i].y] = WHITE; cur_trmno.pos[i].x--; grid[cur_trmno.pos[i].x][cur_trmno.pos[i].y] = cur_trmno.colour; } } if (IsKeyDown(KEY_G)) gen_trmno = true; BeginDrawing(); Draw2DGrid(grid); EndDrawing(); } CloseWindow(); return 0; } void Draw2DGrid(Color grid[WIDTH][HEIGHT]){ int i, j; for (i = 0; i < WIDTH; i++) { for (j = 0; j < HEIGHT; j++) { DrawRectangle(i*FACT, j*FACT, FACT, FACT, grid[i][j]); } } for (i = 0; i <= WIDTH; i++) DrawLine(i*FACT, 0, i*FACT, HEIGHT*FACT, LIGHTGRAY); for (i = 0; i <= HEIGHT; i++) DrawLine(0, i*FACT, WIDTH*FACT, i*FACT, LIGHTGRAY); }