From 9e14338b7789b77223cdfca372c75a4d79fc090e Mon Sep 17 00:00:00 2001 From: Christoffer Lerno Date: Thu, 27 Nov 2025 20:42:35 +0100 Subject: [PATCH] Update raylib examples. --- resources/examples/raylib/raylib_arkanoid.c3 | 395 +++--- resources/examples/raylib/raylib_snake.c3 | 276 ++--- resources/examples/raylib/raylib_tetris.c3 | 1126 +++++++++--------- 3 files changed, 869 insertions(+), 928 deletions(-) diff --git a/resources/examples/raylib/raylib_arkanoid.c3 b/resources/examples/raylib/raylib_arkanoid.c3 index eec52c1d1..729dab18a 100644 --- a/resources/examples/raylib/raylib_arkanoid.c3 +++ b/resources/examples/raylib/raylib_arkanoid.c3 @@ -1,5 +1,5 @@ module arkanoid; -import raylib5; +import raylib55; import std::math; /** * @@ -34,23 +34,23 @@ enum GameScreen struct Player { - Vector2 position; - Vector2 size; - int life; + RLVector2 position; + RLVector2 size; + int life; } struct Ball { - Vector2 position; - Vector2 speed; - int radius; - bool active; + RLVector2 position; + RLVector2 speed; + int radius; + bool active; } struct Brick { - Vector2 position; - bool active; + RLVector2 position; + bool active; } //------------------------------------------------------------------------------------ @@ -63,36 +63,36 @@ bool pause = false; Player player; Ball ball; Brick[BRICKS_PER_LINE][LINES_OF_BRICKS] brick; -Vector2 brick_size; +RLVector2 brick_size; //------------------------------------------------------------------------------------ // Program main entry point //------------------------------------------------------------------------------------ fn void main() { - // Initialization (Note windowTitle is unused on Android) - //--------------------------------------------------------- - rl::initWindow(SCREEN_WIDTH, SCREEN_HEIGHT, "classic game: arkanoid"); + // Initialization (Note windowTitle is unused on Android) + //--------------------------------------------------------- + rl::init_window(SCREEN_WIDTH, SCREEN_HEIGHT, "classic game: arkanoid"); init_game(); - rl::setTargetFPS(60); - //-------------------------------------------------------------------------------------- + rl::set_target_fps(60); + //-------------------------------------------------------------------------------------- - // Main game loop - while (!rl::windowShouldClose()) // Detect window close button or ESC key - { - // Update and Draw - //---------------------------------------------------------------------------------- - update_draw_frame(); - //---------------------------------------------------------------------------------- - } - // De-Initialization - //-------------------------------------------------------------------------------------- - unload_game(); // Unload loaded data (textures, sounds, models...) + // Main game loop + while (!rl::window_should_close()) // Detect window close button or ESC key + { + // Update and Draw + //---------------------------------------------------------------------------------- + update_draw_frame(); + //---------------------------------------------------------------------------------- + } + // De-Initialization + //-------------------------------------------------------------------------------------- + unload_game(); // Unload loaded data (textures, sounds, models...) - rl::closeWindow(); // Close window and OpenGL context - //-------------------------------------------------------------------------------------- + rl::close_window(); // Close window and OpenGL context + //-------------------------------------------------------------------------------------- } @@ -103,30 +103,30 @@ fn void main() // Initialize game variables fn void init_game() { - brick_size = { (float)rl::getScreenWidth() / BRICKS_PER_LINE, 40 }; + brick_size = { (float)rl::get_screen_width() / BRICKS_PER_LINE, 40 }; - // Initialize player - player.position = { SCREEN_WIDTH/2, SCREEN_HEIGHT * 7 / 8 }; - player.size = { SCREEN_WIDTH / 10, 20 }; - player.life = PLAYER_MAX_LIFE; + // Initialize player + player.position = { SCREEN_WIDTH / 2, SCREEN_HEIGHT * 7 / 8 }; + player.size = { SCREEN_WIDTH / 10, 20 }; + player.life = PLAYER_MAX_LIFE; - // Initialize ball - ball.position = { SCREEN_WIDTH / 2, SCREEN_HEIGHT * 7 / 8 - 30 }; - ball.speed = { 0, 0 }; - ball.radius = 7; - ball.active = false; + // Initialize ball + ball.position = { SCREEN_WIDTH / 2, SCREEN_HEIGHT * 7 / 8 - 30 }; + ball.speed = { 0, 0 }; + ball.radius = 7; + ball.active = false; - // Initialize bricks - int initial_down_position = 50; + // Initialize bricks + int initial_down_position = 50; - for (int i = 0; i < LINES_OF_BRICKS; i++) - { - for (int j = 0; j < BRICKS_PER_LINE; j++) - { - brick[i][j].position = { j * brick_size.x + brick_size.x / 2, i * brick_size.y + initial_down_position }; - brick[i][j].active = true; - } - } + for (int i = 0; i < LINES_OF_BRICKS; i++) + { + for (int j = 0; j < BRICKS_PER_LINE; j++) + { + brick[i][j].position = { j * brick_size.x + brick_size.x / 2, i * brick_size.y + initial_down_position }; + brick[i][j].active = true; + } + } } // Update game (one frame) @@ -134,178 +134,187 @@ fn void update_game() { if (game_over) { - if (rl::isKeyPressed(rl::KEY_ENTER)) - { - init_game(); - game_over = false; - } + if (rl::is_key_pressed(ENTER)) + { + init_game(); + game_over = false; + } } - if (rl::isKeyPressed((KeyboardKey)'P')) pause = !pause; + if (rl::is_key_pressed(P)) pause = !pause; if (pause) return; - // Player movement logic - if (rl::isKeyDown(rl::KEY_LEFT)) player.position.x -= 5; - if ((player.position.x - player.size.x/2) <= 0) player.position.x = player.size.x/2; - if (rl::isKeyDown(rl::KEY_RIGHT)) player.position.x += 5; - if ((player.position.x + player.size.x/2) >= SCREEN_WIDTH) player.position.x = SCREEN_WIDTH - player.size.x/2; + // Player movement logic + if (rl::is_key_down(LEFT)) player.position.x -= 5; + if ((player.position.x - player.size.x / 2) <= 0) player.position.x = player.size.x / 2; + if (rl::is_key_down(RIGHT)) player.position.x += 5; + if ((player.position.x + player.size.x / 2) >= SCREEN_WIDTH) player.position.x = SCREEN_WIDTH - player.size.x / 2; - // Ball launching logic - if (!ball.active) - { - if (rl::isKeyPressed(rl::KEY_SPACE)) - { - ball.active = true; - ball.speed = { 0, -5 }; - } - } + // Ball launching logic + if (!ball.active) + { + if (rl::is_key_pressed(SPACE)) + { + ball.active = true; + ball.speed = { 0, -5 }; + } + } - // Ball movement logic - if (ball.active) - { - ball.position.x += ball.speed.x; - ball.position.y += ball.speed.y; - } - else - { - ball.position = { player.position.x, SCREEN_HEIGHT * 7 / 8 - 30 }; - } + // Ball movement logic + if (ball.active) + { - // Collision logic: ball vs walls - if (((ball.position.x + ball.radius) >= SCREEN_WIDTH) || ((ball.position.x - ball.radius) <= 0)) ball.speed.x *= -1; - if ((ball.position.y - ball.radius) <= 0) ball.speed.y *= -1; - if ((ball.position.y + ball.radius) >= SCREEN_HEIGHT) - { - ball.speed = { 0, 0 }; - ball.active = false; + ball.position += ball.speed; + } + else + { + ball.position = { player.position.x, SCREEN_HEIGHT * 7 / 8 - 30 }; + } - player.life--; - } + // Collision logic: ball vs walls - // Collision logic: ball vs player - if (rl::checkCollisionCircleRec(ball.position, ball.radius, { player.position.x - player.size.x / 2, player.position.y - player.size.y / 2, player.size.x, player.size.y})) - { - if (ball.speed.y > 0) - { - ball.speed.y *= -1; - ball.speed.x = (ball.position.x - player.position.x) / (player.size.x / 2) * 5; - } - } + if ((ball.position.x + ball.radius >= SCREEN_WIDTH) || (ball.position.x - ball.radius <= 0)) ball.speed.x *= -1; + if (ball.position.y - ball.radius <= 0) ball.speed.y *= -1; + if (ball.position.y + ball.radius >= SCREEN_HEIGHT) + { + ball.speed = { 0, 0 }; + ball.active = false; + player.life--; + } - // Collision logic: ball vs bricks - for (int i = 0; i < LINES_OF_BRICKS; i++) - { - for (int j = 0; j < BRICKS_PER_LINE; j++) - { - if (brick[i][j].active) - { - // Hit below - if (((ball.position.y - ball.radius) <= (brick[i][j].position.y + brick_size.y / 2)) && - ((ball.position.y - ball.radius) > (brick[i][j].position.y + brick_size.y / 2 + ball.speed.y)) && - ((math::abs(ball.position.x - brick[i][j].position.x)) < (brick_size.x / 2 + ball.radius * 2.0f / 3)) && (ball.speed.y < 0)) - { - brick[i][j].active = false; - ball.speed.y *= -1; - } - // Hit above - else if (((ball.position.y + ball.radius) >= (brick[i][j].position.y - brick_size.y/2)) && - ((ball.position.y + ball.radius) < (brick[i][j].position.y - brick_size.y/2 + ball.speed.y)) && - ((math::abs(ball.position.x - brick[i][j].position.x)) < (brick_size.x / 2 + ball.radius * 2.0f / 3)) && (ball.speed.y > 0)) - { - brick[i][j].active = false; - ball.speed.y *= -1; - } - // Hit left - else if (((ball.position.x + ball.radius) >= (brick[i][j].position.x - brick_size.x/2)) && - ((ball.position.x + ball.radius) < (brick[i][j].position.x - brick_size.x/2 + ball.speed.x)) && - ((math::abs(ball.position.y - brick[i][j].position.y)) < (brick_size.y / 2 + ball.radius * 2.0f / 3)) && (ball.speed.x > 0)) - { - brick[i][j].active = false; - ball.speed.x *= -1; - } - // Hit right - else if (((ball.position.x - ball.radius) <= (brick[i][j].position.x + brick_size.x/2)) && - ((ball.position.x - ball.radius) > (brick[i][j].position.x + brick_size.x/2 + ball.speed.x)) && - ((math::abs(ball.position.y - brick[i][j].position.y)) < (brick_size.y / 2 + ball.radius * 2.0f / 3)) && (ball.speed.x < 0)) - { - brick[i][j].active = false; - ball.speed.x *= -1; - } - } - } - } + // Collision logic: ball vs player + if (rl::check_collision_circle_rec(ball.position, ball.radius, { player.position.x - player.size.x / 2, player.position.y - player.size.y / 2, player.size.x, player.size.y})) + { + if (ball.speed.y > 0) + { + ball.speed.y *= -1; + ball.speed.x = (ball.position.x - player.position.x) / (player.size.x / 2) * 5; + } + } - // Game over logic - if (player.life <= 0) - { - game_over = true; - } - else - { - game_over = true; - for (int i = 0; i < LINES_OF_BRICKS; i++) - { - for (int j = 0; j < BRICKS_PER_LINE; j++) - { - if (brick[i][j].active) game_over = false; - } - } - } + // Collision logic: ball vs bricks + for (int i = 0; i < LINES_OF_BRICKS; i++) + { + for (int j = 0; j < BRICKS_PER_LINE; j++) + { + if (brick[i][j].active) + { + // Hit below + + if (ball.position.y - ball.radius <= brick[i][j].position.y + brick_size.y / 2 + && ball.position.y - ball.radius > brick[i][j].position.y + brick_size.y / 2 + ball.speed.y + && math::abs(ball.position.x - brick[i][j].position.x) < brick_size.x / 2 + ball.radius * 2.0f / 3 + && ball.speed.y < 0) + { + brick[i][j].active = false; + ball.speed.y *= -1; + } + // Hit above + else if (ball.position.y + ball.radius >= brick[i][j].position.y - brick_size.y / 2 + && ball.position.y + ball.radius < brick[i][j].position.y - brick_size.y/2 + ball.speed.y + && math::abs(ball.position.x - brick[i][j].position.x) < brick_size.x / 2 + ball.radius * 2.0f / 3 + && ball.speed.y > 0) + { + brick[i][j].active = false; + ball.speed.y *= -1; + } + // Hit left + else if (ball.position.x + ball.radius >= brick[i][j].position.x - brick_size.x / 2 + && ball.position.x + ball.radius < brick[i][j].position.x - brick_size.x / 2 + ball.speed.x + && math::abs(ball.position.y - brick[i][j].position.y) < brick_size.y / 2 + ball.radius * 2.0f / 3 + && ball.speed.x > 0) + { + brick[i][j].active = false; + ball.speed.x *= -1; + } + // Hit right + else if (ball.position.x - ball.radius <= brick[i][j].position.x + brick_size.x / 2 + && ball.position.x - ball.radius > brick[i][j].position.x + brick_size.x / 2 + ball.speed.x + && math::abs(ball.position.y - brick[i][j].position.y) < brick_size.y / 2 + ball.radius * 2.0f / 3 + && ball.speed.x < 0) + { + brick[i][j].active = false; + ball.speed.x *= -1; + } + } + } + } + + // Game over logic + if (player.life <= 0) + { + game_over = true; + return; + } + for (int i = 0; i < LINES_OF_BRICKS; i++) + { + for (int j = 0; j < BRICKS_PER_LINE; j++) + { + if (brick[i][j].active) + { + game_over = false; + return; + } + } + } + game_over = true; } // Draw game (one frame) fn void draw_game() { - rl::beginDrawing(); - defer rl::endDrawing(); - rl::clearBackground(rl::RAYWHITE); + rl::begin_drawing(); + defer rl::end_drawing(); - if (!game_over) - { - // Draw player bar - rl::drawRectangle((int)(player.position.x - player.size.x/2), (int)(player.position.y - player.size.y/2), (int)player.size.x, (int)player.size.y, rl::BLACK); + rl::clear_background(rl::RAYWHITE); - // Draw player lives - for (int i = 0; i < player.life; i++) rl::drawRectangle(20 + 40*i, SCREEN_HEIGHT - 30, 35, 10, rl::LIGHTGRAY); + if (!game_over) + { + // Draw player bar + rl::draw_rectangle((int)(player.position.x - player.size.x/2), (int)(player.position.y - player.size.y/2), (int)player.size.x, (int)player.size.y, rl::BLACK); - // Draw ball - rl::drawCircleV(ball.position, ball.radius, rl::MAROON); + // Draw player lives + for (int i = 0; i < player.life; i++) rl::draw_rectangle(20 + 40*i, SCREEN_HEIGHT - 30, 35, 10, rl::LIGHTGRAY); - // Draw bricks - for (int i = 0; i < LINES_OF_BRICKS; i++) - { - for (int j = 0; j < BRICKS_PER_LINE; j++) - { - if (brick[i][j].active) - { - if ((i + j) % 2 == 0) - { - rl::drawRectangle((int)(brick[i][j].position.x - brick_size.x/2), (int)(brick[i][j].position.y - brick_size.y/2), (int)brick_size.x, (int)brick_size.y, rl::GRAY); - } - else - { - rl::drawRectangle((int)(brick[i][j].position.x - brick_size.x/2), (int)(brick[i][j].position.y - brick_size.y/2), (int)brick_size.x, (int)brick_size.y, rl::DARKGRAY); - } - } - } - } + // Draw ball + rl::draw_circle_v(ball.position, ball.radius, rl::MAROON); - if (pause) rl::drawText("GAME PAUSED", SCREEN_WIDTH/2 - rl::measureText("GAME PAUSED", 40)/2, SCREEN_HEIGHT/2 - 40, 40, rl::GRAY); - } - else - { - rl::drawText("PRESS [ENTER] TO PLAY AGAIN", rl::getScreenWidth()/2 - rl::measureText("PRESS [ENTER] TO PLAY AGAIN", 20)/2, rl::getScreenHeight()/2 - 50, 20, rl::GRAY); - } + // Draw bricks + for (int i = 0; i < LINES_OF_BRICKS; i++) + { + for (int j = 0; j < BRICKS_PER_LINE; j++) + { + if (brick[i][j].active) + { + RLVector2 brick_pos = brick[i][j].position - brick_size / 2; + if ((i + j) % 2 == 0) + { + rl::draw_rectangle((int)brick_pos.x, (int)brick_pos.y, (int)brick_size.x, (int)brick_size.y, rl::GRAY); + } + else + { + rl::draw_rectangle((int)brick_pos.x, (int)brick_pos.y, (int)brick_size.x, (int)brick_size.y, rl::DARKGRAY); + } + } + } + } + + if (pause) rl::draw_text("GAME PAUSED", SCREEN_WIDTH / 2 - rl::measure_text("GAME PAUSED", 40) / 2, SCREEN_HEIGHT / 2 - 40, 40, rl::GRAY); + } + else + { + rl::draw_text("PRESS [ENTER] TO PLAY AGAIN", rl::get_screen_width()/2 - rl::measure_text("PRESS [ENTER] TO PLAY AGAIN", 20) / 2, rl::get_screen_height() / 2 - 50, 20, rl::GRAY); + } } // Unload game variables fn void unload_game() { - // TODO: Unload all dynamic loaded data (textures, sounds, models...) + // TODO: Unload all dynamic loaded data (textures, sounds, models...) } // Update and Draw (one frame) fn void update_draw_frame() { - update_game(); - draw_game(); + update_game(); + draw_game(); } \ No newline at end of file diff --git a/resources/examples/raylib/raylib_snake.c3 b/resources/examples/raylib/raylib_snake.c3 index 0fa6348cf..f25fab7fe 100644 --- a/resources/examples/raylib/raylib_snake.c3 +++ b/resources/examples/raylib/raylib_snake.c3 @@ -1,5 +1,5 @@ module snake; -import raylib5; +import raylib55; /** * * raylib - classic game: snake @@ -16,26 +16,26 @@ const SQUARE_SIZE = 32; const int SCREEN_WIDTH = 800; const int SCREEN_HEIGHT = 450; -enum SnakeDirection +enum SnakeDirection : (RLVector2 dir) { - RIGHT, - DOWN, - LEFT, - UP + RIGHT = { SQUARE_SIZE, 0 }, + DOWN = { 0, SQUARE_SIZE }, + LEFT = { -SQUARE_SIZE, 0 }, + UP = { 0, -SQUARE_SIZE } } struct Snake { - Vector2 position; - Vector2 size; - Color color; + RLVector2 position; + RLVector2 size; + RLColor color; } struct Food { - Vector2 position; - Vector2 size; - bool active; - Color color; + RLVector2 position; + RLVector2 size; + bool active; + RLColor color; } @@ -46,201 +46,169 @@ bool pause = false; Food fruit; SnakeDirection snake_direction; Snake[SNAKE_LENGTH] snake; -Vector2[SNAKE_LENGTH] snake_position; +RLVector2[SNAKE_LENGTH] snake_position; bool allow_move = false; -Vector2 offset; +RLVector2 offset; int counter_tail = 0; fn void main() { - rl::initWindow(SCREEN_WIDTH, SCREEN_HEIGHT, "classic game: snake"); + rl::init_window(SCREEN_WIDTH, SCREEN_HEIGHT, "classic game: snake"); init_game(); - rl::setTargetFPS(60); + rl::set_target_fps(60); - while (!rl::windowShouldClose()) // Detect window close button or ESC key - { - update_draw_frame(); - } + while (!rl::window_should_close()) // Detect window close button or ESC key + { + update_draw_frame(); + } - unload_game(); + unload_game(); - rl::closeWindow(); + rl::close_window(); } - // Initialize game variables fn void init_game() { - frames_counter = 0; - game_over = false; - pause = false; + frames_counter = 0; + game_over = false; + pause = false; - counter_tail = 1; - allow_move = false; + counter_tail = 1; + allow_move = false; snake_direction = RIGHT; - offset.x = SCREEN_WIDTH % SQUARE_SIZE; - offset.y = SCREEN_HEIGHT % SQUARE_SIZE; + offset.x = SCREEN_WIDTH % SQUARE_SIZE; + offset.y = SCREEN_HEIGHT % SQUARE_SIZE; + foreach (i, &s : snake) + { + s.position = offset / 2; + s.size = (RLVector2)SQUARE_SIZE; + s.color = i ? rl::BLUE : rl::DARKBLUE; + } - for (int i = 0; i < SNAKE_LENGTH; i++) - { - snake[i].position = { offset.x / 2, offset.y / 2 }; - snake[i].size = { SQUARE_SIZE, SQUARE_SIZE }; + foreach (&pos : snake_position) + { + *pos = { 0, 0 }; + } - if (i == 0) - { - snake[i].color = rl::DARKBLUE; - } - else - { - snake[i].color = rl::BLUE; - } - } - - for (int i = 0; i < SNAKE_LENGTH; i++) - { - snake_position[i] = { 0.0f, 0.0f }; - } - - fruit.size = { SQUARE_SIZE, SQUARE_SIZE }; - fruit.color = rl::SKYBLUE; - fruit.active = false; + fruit = { .size = (RLVector2)SQUARE_SIZE, .color = rl::SKYBLUE, .active = false }; } +fn RLVector2 random_fruit_position() +{ + return offset / 2 + { (float)rl::get_random_value(0, SCREEN_WIDTH / SQUARE_SIZE - 1) * SQUARE_SIZE, (float)rl::get_random_value(0, (SCREEN_HEIGHT / SQUARE_SIZE) - 1) * SQUARE_SIZE }; +} fn void update_game() { if (game_over) { - if (rl::isKeyPressed(rl::KEY_ENTER)) - { - init_game(); - game_over = false; - } + if (rl::is_key_pressed(ENTER)) + { + init_game(); + game_over = false; + } return; } - if (rl::isKeyPressed((KeyboardKey)'P')) pause = !pause; + if (rl::is_key_pressed(P)) pause = !pause; if (pause) return; - if (rl::isKeyPressed(rl::KEY_RIGHT) && allow_move) - { - snake_direction = SnakeDirection.from_ordinal((snake_direction.ordinal + 1) % 4); - allow_move = false; - } - if (rl::isKeyPressed(rl::KEY_LEFT) && allow_move) - { - snake_direction = SnakeDirection.from_ordinal((snake_direction.ordinal + 3) % 4); - allow_move = false; - } - - // Snake movement - for (int i = 0; i < counter_tail; i++) snake_position[i] = snake[i].position; - - if (frames_counter++ % 5 != 0) return; - - allow_move = true; - switch (snake_direction) + if (rl::is_key_pressed(RIGHT) && allow_move) { - case RIGHT: - snake[0].position.x += SQUARE_SIZE; - snake[0].position.y += 0; - case UP: - snake[0].position.x += 0; - snake[0].position.y += -SQUARE_SIZE; - case DOWN: - snake[0].position.x += 0; - snake[0].position.y += SQUARE_SIZE; - case LEFT: - snake[0].position.x += -SQUARE_SIZE; - snake[0].position.y += 0; - default: - unreachable(); + snake_direction = SnakeDirection.from_ordinal((snake_direction.ordinal + 1) % 4); + allow_move = false; + } + if (rl::is_key_pressed(LEFT) && allow_move) + { + snake_direction = SnakeDirection.from_ordinal((snake_direction.ordinal + 3) % 4); + allow_move = false; } - for (int i = 1; i < counter_tail; i++) - { - snake[i].position = snake_position[i - 1]; - } - // Wall behaviour - if (((snake[0].position.x) > (SCREEN_WIDTH - offset.x)) || - ((snake[0].position.y) > (SCREEN_HEIGHT - offset.y)) || - (snake[0].position.x < 0) || (snake[0].position.y < 0)) - { - game_over = true; - } + // Snake movement + foreach (i, &sp : snake_position[:counter_tail]) *sp = snake[i].position; - // Collision with yourself - for (int i = 1; i < counter_tail; i++) - { - if ((snake[0].position.x == snake[i].position.x) && (snake[0].position.y == snake[i].position.y)) game_over = true; - } + if (frames_counter++ % 20 != 0) return; - // Fruit position calculation - if (!fruit.active) - { - fruit.active = true; - fruit.position = { (float)rl::getRandomValue(0, (SCREEN_WIDTH / SQUARE_SIZE) - 1) * SQUARE_SIZE + offset.x / 2, (float)rl::getRandomValue(0, (SCREEN_HEIGHT / SQUARE_SIZE) - 1) * SQUARE_SIZE + offset.y / 2 }; + allow_move = true; + snake[0].position += snake_direction.dir; + foreach (i, &s : snake[1 .. counter_tail - 1]) s.position = snake_position[i]; - for (int i = 0; i < counter_tail; i++) - { - while ((fruit.position.x == snake[i].position.x) && (fruit.position.y == snake[i].position.y)) - { - fruit.position = { (float)rl::getRandomValue(0, (SCREEN_WIDTH / SQUARE_SIZE) - 1) * SQUARE_SIZE + offset.x/2, (float)rl::getRandomValue(0, (SCREEN_HEIGHT / SQUARE_SIZE) - 1) * SQUARE_SIZE + offset.y / 2 }; - i = 0; - } - } - } + // Wall behaviour + if (snake[0].position.comp_ge({SCREEN_WIDTH - offset.x, SCREEN_HEIGHT - offset.y}).or() || snake[0].position.comp_lt({ 0, 0 }).or()) + { + game_over = true; + } - // Collision - if ((snake[0].position.x < (fruit.position.x + fruit.size.x) && (snake[0].position.x + snake[0].size.x) > fruit.position.x) && - (snake[0].position.y < (fruit.position.y + fruit.size.y) && (snake[0].position.y + snake[0].size.y) > fruit.position.y)) - { - snake[counter_tail].position = snake_position[counter_tail - 1]; - counter_tail += 1; - fruit.active = false; - } + // Collision with yourself + for (int i = 1; i < counter_tail; i++) + { + if (snake[0].position == snake[i].position) game_over = true; + } + + // Fruit position calculation + if (!fruit.active) + { + fruit.active = true; + fruit.position = random_fruit_position(); + + for (int i = 0; i < counter_tail; i++) + { + while (fruit.position == snake[i].position) + { + fruit.position = random_fruit_position(); + i = 0; + } + } + } + + // Collision + if (snake[0].position.comp_lt(fruit.position + fruit.size).and() && fruit.position.comp_lt(snake[0].position + snake[0].size).and()) + { + snake[counter_tail].position = snake_position[counter_tail - 1]; + counter_tail += 1; + fruit.active = false; + } } // Draw game (one frame) fn void draw_game() { - rl::beginDrawing(); + rl::begin_drawing(); - rl::clearBackground(rl::RAYWHITE); + rl::clear_background(rl::RAYWHITE); - if (!game_over) - { - // Draw grid lines - for (int i = 0; i < SCREEN_WIDTH / SQUARE_SIZE + 1; i++) - { - rl::drawLineV({(float)SQUARE_SIZE * i + offset.x/2, offset.y/2}, {(float)SQUARE_SIZE * i + offset.x/2, SCREEN_HEIGHT - offset.y/2}, rl::LIGHTGRAY); - } + defer rl::end_drawing(); + if (game_over) + { + rl::draw_text("PRESS [ENTER] TO PLAY AGAIN", rl::get_screen_width() / 2 - rl::measure_text("PRESS [ENTER] TO PLAY AGAIN", 20)/2, rl::get_screen_height() / 2 - 50, 20, rl::GRAY); + return; + } + // Draw grid lines + for (int i = 0; i < SCREEN_WIDTH / SQUARE_SIZE + 1; i++) + { + rl::draw_line_v(offset / 2 + { (float)SQUARE_SIZE * i, 0}, {(float)SQUARE_SIZE * i + offset.x / 2, SCREEN_HEIGHT - offset.y / 2}, rl::LIGHTGRAY); + } - for (int i = 0; i < SCREEN_HEIGHT/SQUARE_SIZE + 1; i++) - { - rl::drawLineV({offset.x/2, (float)SQUARE_SIZE * i + offset.y / 2 }, { SCREEN_WIDTH - offset.x/2, (float)SQUARE_SIZE * i + offset.y / 2 }, rl::LIGHTGRAY); - } + for (int i = 0; i < SCREEN_HEIGHT/SQUARE_SIZE + 1; i++) + { + rl::draw_line_v(offset / 2 + { 0, (float)SQUARE_SIZE * i }, { SCREEN_WIDTH - offset.x/2, (float)SQUARE_SIZE * i + offset.y / 2 }, rl::LIGHTGRAY); + } - // Draw snake - for (int i = 0; i < counter_tail; i++) rl::drawRectangleV(snake[i].position, snake[i].size, snake[i].color); + // Draw snake + foreach (&s : snake[:counter_tail]) rl::draw_rectangle_v(s.position, s.size, s.color); - // Draw fruit to pick - rl::drawRectangleV(fruit.position, fruit.size, fruit.color); + // Draw fruit to pick + rl::draw_rectangle_v(fruit.position, fruit.size, fruit.color); - if (pause) rl::drawText("GAME PAUSED", SCREEN_WIDTH/2 - rl::measureText("GAME PAUSED", 40)/2, SCREEN_HEIGHT / 2 - 40, 40, rl::GRAY); - } - else - { - rl::drawText("PRESS [ENTER] TO PLAY AGAIN", rl::getScreenWidth()/2 - rl::measureText("PRESS [ENTER] TO PLAY AGAIN", 20)/2, rl::getScreenHeight()/2 - 50, 20, rl::GRAY); - } + if (pause) rl::draw_text("GAME PAUSED", SCREEN_WIDTH / 2 - rl::measure_text("GAME PAUSED", 40) / 2, SCREEN_HEIGHT / 2 - 40, 40, rl::GRAY); - rl::endDrawing(); } // Unload game variables fn void unload_game() { - // TODO: Unload all dynamic loaded data (textures, sounds, models...) + // TODO: Unload all dynamic loaded data (textures, sounds, models...) } // Update and Draw (one frame) diff --git a/resources/examples/raylib/raylib_tetris.c3 b/resources/examples/raylib/raylib_tetris.c3 index 93bcd306a..d345dfef7 100644 --- a/resources/examples/raylib/raylib_tetris.c3 +++ b/resources/examples/raylib/raylib_tetris.c3 @@ -1,5 +1,5 @@ module tetris; -import raylib5; +import raylib55; /** * raylib - classic game: tetris * @@ -42,17 +42,12 @@ GridSquare[GRID_VERTICAL_SIZE][GRID_HORIZONTAL_SIZE] grid; GridSquare[4][4] piece; GridSquare[4][4] incoming_piece; -struct IntVec -{ - int x; - int y; -} // These variables keep track of the active piece position int piece_position_x = 0; int piece_position_y = 0; // Game parameters -Color fading_color; +RLColor fading_color; //int fallingSpeed; // In frames bool begin_play = true; // This var is only true at the begining of the game, used for the first matrix creations @@ -81,29 +76,29 @@ int gravity_speed = 30; //------------------------------------------------------------------------------------ fn void main() { - // Initialization (Note windowTitle is unused on Android) - //--------------------------------------------------------- - rl::initWindow(SCREEN_WIDTH, SCREEN_HEIGHT, "classic game: tetris"); + // Initialization (Note windowTitle is unused on Android) + //--------------------------------------------------------- + rl::init_window(SCREEN_WIDTH, SCREEN_HEIGHT, "classic game: tetris"); - init_game(); + init_game(); - rl::setTargetFPS(60); - //-------------------------------------------------------------------------------------- + rl::set_target_fps(60); + //-------------------------------------------------------------------------------------- - // Main game loop - while (!rl::windowShouldClose()) // Detect window close button or ESC key - { - // Update and Draw - //---------------------------------------------------------------------------------- - update_draw_frame(); - //---------------------------------------------------------------------------------- - } - // De-Initialization - //-------------------------------------------------------------------------------------- - unload_game(); // Unload loaded data (textures, sounds, models...) + // Main game loop + while (!rl::window_should_close()) // Detect window close button or ESC key + { + // Update and Draw + //---------------------------------------------------------------------------------- + update_draw_frame(); + //---------------------------------------------------------------------------------- + } + // De-Initialization + //-------------------------------------------------------------------------------------- + unload_game(); // Unload loaded data (textures, sounds, models...) - rl::closeWindow(); // Close window and OpenGL context - //-------------------------------------------------------------------------------------- + rl::close_window(); // Close window and OpenGL context + //-------------------------------------------------------------------------------------- } @@ -114,55 +109,55 @@ fn void main() // Initialize game variables fn void init_game() { - // Initialize game statistics - level = 1; - lines = 0; + // Initialize game statistics + level = 1; + lines = 0; - fading_color = rl::GRAY; + fading_color = rl::GRAY; - piece_position_x = 0; - piece_position_y = 0; + piece_position_x = 0; + piece_position_y = 0; - pause = false; + pause = false; - begin_play = true; - piece_active = false; - detection = false; - line_to_delete = false; + begin_play = true; + piece_active = false; + detection = false; + line_to_delete = false; - // Counters - gravity_movement_counter = 0; - lateral_movement_counter = 0; - turn_movement_counter = 0; - fast_fall_movement_counter = 0; + // Counters + gravity_movement_counter = 0; + lateral_movement_counter = 0; + turn_movement_counter = 0; + fast_fall_movement_counter = 0; - fade_line_counter = 0; - gravity_speed = 30; + fade_line_counter = 0; + gravity_speed = 30; - // Initialize grid matrices - for (int i = 0; i < GRID_HORIZONTAL_SIZE; i++) - { - for (int j = 0; j < GRID_VERTICAL_SIZE; j++) - { - if ((j == GRID_VERTICAL_SIZE - 1) || (i == 0) || (i == GRID_HORIZONTAL_SIZE - 1)) - { - grid[i][j] = BLOCK; - } - else - { - grid[i][j] = EMPTY; - } - } - } + // Initialize grid matrices + for (int i = 0; i < GRID_HORIZONTAL_SIZE; i++) + { + for (int j = 0; j < GRID_VERTICAL_SIZE; j++) + { + if ((j == GRID_VERTICAL_SIZE - 1) || (i == 0) || (i == GRID_HORIZONTAL_SIZE - 1)) + { + grid[i][j] = BLOCK; + } + else + { + grid[i][j] = EMPTY; + } + } + } - // Initialize incoming piece matrices - for (int i = 0; i < 4; i++) - { - for (int j = 0; j< 4; j++) - { - incoming_piece[i][j] = EMPTY; - } - } + // Initialize incoming piece matrices + for (int i = 0; i < 4; i++) + { + for (int j = 0; j< 4; j++) + { + incoming_piece[i][j] = EMPTY; + } + } } // Update game (one frame) @@ -170,206 +165,206 @@ fn void update_game() { if (game_over) { - if (rl::isKeyPressed(rl::KEY_ENTER)) - { - init_game(); - game_over = false; - } + if (rl::is_key_pressed(ENTER)) + { + init_game(); + game_over = false; + } return; } - if (rl::isKeyPressed((KeyboardKey)'P')) pause = !pause; + if (rl::is_key_pressed(P)) pause = !pause; if (pause) return; if (line_to_delete) { - // Animation when deleting lines - fade_line_counter++; + // Animation when deleting lines + fade_line_counter++; fading_color = fade_line_counter % 8 < 4 ? rl::MAROON : rl::GRAY; - if (fade_line_counter >= FADING_TIME) - { - lines += delete_complete_lines(); - fade_line_counter = 0; - line_to_delete = false; - } - return; + if (fade_line_counter >= FADING_TIME) + { + lines += delete_complete_lines(); + fade_line_counter = 0; + line_to_delete = false; + } + return; } - if (!piece_active) - { - // Get another piece - piece_active = create_piece(); + if (!piece_active) + { + // Get another piece + piece_active = create_piece(); - // We leave a little time before starting the fast falling down - fast_fall_movement_counter = 0; - } - else // Piece falling - { - // Counters update - fast_fall_movement_counter++; - gravity_movement_counter++; - lateral_movement_counter++; - turn_movement_counter++; + // We leave a little time before starting the fast falling down + fast_fall_movement_counter = 0; + } + else // Piece falling + { + // Counters update + fast_fall_movement_counter++; + gravity_movement_counter++; + lateral_movement_counter++; + turn_movement_counter++; - // We make sure to move if we've pressed the key this frame - if (rl::isKeyPressed(rl::KEY_LEFT) || rl::isKeyPressed(rl::KEY_RIGHT)) lateral_movement_counter = LATERAL_SPEED; - if (rl::isKeyPressed(rl::KEY_UP)) turn_movement_counter = TURNING_SPEED; + // We make sure to move if we've pressed the key this frame + if (rl::is_key_pressed(LEFT) || rl::is_key_pressed(RIGHT)) lateral_movement_counter = LATERAL_SPEED; + if (rl::is_key_pressed(UP)) turn_movement_counter = TURNING_SPEED; - // Fall down - if (rl::isKeyDown(rl::KEY_DOWN) && (fast_fall_movement_counter >= FAST_FALL_AWAIT_COUNTER)) - { - // We make sure the piece is going to fall this frame - gravity_movement_counter += gravity_speed; - } + // Fall down + if (rl::is_key_down(DOWN) && (fast_fall_movement_counter >= FAST_FALL_AWAIT_COUNTER)) + { + // We make sure the piece is going to fall this frame + gravity_movement_counter += gravity_speed; + } - if (gravity_movement_counter >= gravity_speed) - { - // Basic falling movement - if (check_detection()) detection = true; + if (gravity_movement_counter >= gravity_speed) + { + // Basic falling movement + if (check_detection()) detection = true; - // Check if the piece has collided with another piece or with the boundings - resolve_falling_movement(&detection, &piece_active); + // Check if the piece has collided with another piece or with the boundings + resolve_falling_movement(&detection, &piece_active); - // Check if we fullfilled a line and if so, erase the line and pull down the the lines above - check_completion(&line_to_delete); + // Check if we fullfilled a line and if so, erase the line and pull down the the lines above + check_completion(&line_to_delete); - gravity_movement_counter = 0; - } + gravity_movement_counter = 0; + } - // Move laterally at player's will - if (lateral_movement_counter >= LATERAL_SPEED) - { - // Update the lateral movement and if success, reset the lateral counter - if (!resolve_lateral_movement()) lateral_movement_counter = 0; - } + // Move laterally at player's will + if (lateral_movement_counter >= LATERAL_SPEED) + { + // Update the lateral movement and if success, reset the lateral counter + if (!resolve_lateral_movement()) lateral_movement_counter = 0; + } - // Turn the piece at player's will - if (turn_movement_counter >= TURNING_SPEED) - { - // Update the turning movement and reset the turning counter - if (resolve_turn_movement()) turn_movement_counter = 0; - } - } + // Turn the piece at player's will + if (turn_movement_counter >= TURNING_SPEED) + { + // Update the turning movement and reset the turning counter + if (resolve_turn_movement()) turn_movement_counter = 0; + } + } - // Game over logic - for (int j = 0; j < 2; j++) - { - for (int i = 1; i < GRID_HORIZONTAL_SIZE - 1; i++) - { - if (grid[i][j] == FULL) - { - game_over = true; - } - } - } + // Game over logic + for (int j = 0; j < 2; j++) + { + for (int i = 1; i < GRID_HORIZONTAL_SIZE - 1; i++) + { + if (grid[i][j] == FULL) + { + game_over = true; + } + } + } } // Draw game (one frame) fn void draw_game() { - rl::beginDrawing(); - defer rl::endDrawing(); - rl::clearBackground(rl::RAYWHITE); + rl::begin_drawing(); + defer rl::end_drawing(); + rl::clear_background(rl::RAYWHITE); if (game_over) { - rl::drawText("PRESS [ENTER] TO PLAY AGAIN", rl::getScreenWidth() / 2 - rl::measureText("PRESS [ENTER] TO PLAY AGAIN", 20) / 2, rl::getScreenHeight() / 2 - 50, 20, rl::GRAY); + rl::draw_text("PRESS [ENTER] TO PLAY AGAIN", rl::get_screen_width() / 2 - rl::measure_text("PRESS [ENTER] TO PLAY AGAIN", 20) / 2, rl::get_screen_height() / 2 - 50, 20, rl::GRAY); return; } - // Draw gameplay area - IntVec offset = { - SCREEN_WIDTH / 2 - (GRID_HORIZONTAL_SIZE * SQUARE_SIZE / 2) - 50, - SCREEN_HEIGHT / 2 - ((GRID_VERTICAL_SIZE - 1) * SQUARE_SIZE / 2) + SQUARE_SIZE * 2 - }; - offset.y -= 50; // NOTE: Harcoded position! + // Draw gameplay area + int[<2>] offset = { + SCREEN_WIDTH / 2 - (GRID_HORIZONTAL_SIZE * SQUARE_SIZE / 2) - 50, + SCREEN_HEIGHT / 2 - ((GRID_VERTICAL_SIZE - 1) * SQUARE_SIZE / 2) + SQUARE_SIZE * 2 + }; + offset.y -= 50; // NOTE: Harcoded position! - int controller = offset.x; + int controller = offset.x; - for (int j = 0; j < GRID_VERTICAL_SIZE; j++) - { - for (int i = 0; i < GRID_HORIZONTAL_SIZE; i++) - { - // Draw each square of the grid - switch (grid[i][j]) - { - case EMPTY: - rl::drawLine(offset.x, offset.y, offset.x + SQUARE_SIZE, offset.y, rl::LIGHTGRAY ); - rl::drawLine(offset.x, offset.y, offset.x, offset.y + SQUARE_SIZE, rl::LIGHTGRAY ); - rl::drawLine(offset.x + SQUARE_SIZE, offset.y, offset.x + SQUARE_SIZE, offset.y + SQUARE_SIZE, rl::LIGHTGRAY ); - rl::drawLine(offset.x, offset.y + SQUARE_SIZE, offset.x + SQUARE_SIZE, offset.y + SQUARE_SIZE, rl::LIGHTGRAY ); - offset.x += SQUARE_SIZE; - case FULL: - rl::drawRectangle(offset.x, offset.y, SQUARE_SIZE, SQUARE_SIZE, rl::GRAY); - offset.x += SQUARE_SIZE; - case MOVING: - rl::drawRectangle(offset.x, offset.y, SQUARE_SIZE, SQUARE_SIZE, rl::DARKGRAY); - offset.x += SQUARE_SIZE; - case BLOCK: - rl::drawRectangle(offset.x, offset.y, SQUARE_SIZE, SQUARE_SIZE, rl::LIGHTGRAY); - offset.x += SQUARE_SIZE; - case FADING: - rl::drawRectangle(offset.x, offset.y, SQUARE_SIZE, SQUARE_SIZE, fading_color); - offset.x += SQUARE_SIZE; - default: - } - } + for (int j = 0; j < GRID_VERTICAL_SIZE; j++) + { + for (int i = 0; i < GRID_HORIZONTAL_SIZE; i++) + { + // Draw each square of the grid + switch (grid[i][j]) + { + case EMPTY: + rl::draw_line_v(offset, offset + { SQUARE_SIZE, 0 }, rl::LIGHTGRAY ); + rl::draw_line(offset.x, offset.y, offset.x, offset.y + SQUARE_SIZE, rl::LIGHTGRAY ); + rl::draw_line(offset.x + SQUARE_SIZE, offset.y, offset.x + SQUARE_SIZE, offset.y + SQUARE_SIZE, rl::LIGHTGRAY ); + rl::draw_line(offset.x, offset.y + SQUARE_SIZE, offset.x + SQUARE_SIZE, offset.y + SQUARE_SIZE, rl::LIGHTGRAY ); + offset.x += SQUARE_SIZE; + case FULL: + rl::draw_rectangle(offset.x, offset.y, SQUARE_SIZE, SQUARE_SIZE, rl::GRAY); + offset.x += SQUARE_SIZE; + case MOVING: + rl::draw_rectangle(offset.x, offset.y, SQUARE_SIZE, SQUARE_SIZE, rl::DARKGRAY); + offset.x += SQUARE_SIZE; + case BLOCK: + rl::draw_rectangle(offset.x, offset.y, SQUARE_SIZE, SQUARE_SIZE, rl::LIGHTGRAY); + offset.x += SQUARE_SIZE; + case FADING: + rl::draw_rectangle(offset.x, offset.y, SQUARE_SIZE, SQUARE_SIZE, fading_color); + offset.x += SQUARE_SIZE; + default: + } + } - offset.x = controller; - offset.y += SQUARE_SIZE; - } + offset.x = controller; + offset.y += SQUARE_SIZE; + } - // Draw incoming piece (hardcoded) - offset.x = 500; - offset.y = 45; + // Draw incoming piece (hardcoded) + offset.x = 500; + offset.y = 45; - controller = offset.x; + controller = offset.x; - for (int j = 0; j < 4; j++) - { - for (int i = 0; i < 4; i++) - { - switch (incoming_piece[i][j]) - { - case EMPTY: - rl::drawLine(offset.x, offset.y, offset.x + SQUARE_SIZE, offset.y, rl::LIGHTGRAY); - rl::drawLine(offset.x, offset.y, offset.x, offset.y + SQUARE_SIZE, rl::LIGHTGRAY); - rl::drawLine(offset.x + SQUARE_SIZE, offset.y, offset.x + SQUARE_SIZE, offset.y + SQUARE_SIZE, rl::LIGHTGRAY); - rl::drawLine(offset.x, offset.y + SQUARE_SIZE, offset.x + SQUARE_SIZE, offset.y + SQUARE_SIZE, rl::LIGHTGRAY); - offset.x += SQUARE_SIZE; - case MOVING: - rl::drawRectangle(offset.x, offset.y, SQUARE_SIZE, SQUARE_SIZE, rl::GRAY); - offset.x += SQUARE_SIZE; - default: - break; - } - } + for (int j = 0; j < 4; j++) + { + for (int i = 0; i < 4; i++) + { + switch (incoming_piece[i][j]) + { + case EMPTY: + rl::draw_line(offset.x, offset.y, offset.x + SQUARE_SIZE, offset.y, rl::LIGHTGRAY); + rl::draw_line(offset.x, offset.y, offset.x, offset.y + SQUARE_SIZE, rl::LIGHTGRAY); + rl::draw_line(offset.x + SQUARE_SIZE, offset.y, offset.x + SQUARE_SIZE, offset.y + SQUARE_SIZE, rl::LIGHTGRAY); + rl::draw_line(offset.x, offset.y + SQUARE_SIZE, offset.x + SQUARE_SIZE, offset.y + SQUARE_SIZE, rl::LIGHTGRAY); + offset.x += SQUARE_SIZE; + case MOVING: + rl::draw_rectangle(offset.x, offset.y, SQUARE_SIZE, SQUARE_SIZE, rl::GRAY); + offset.x += SQUARE_SIZE; + default: + break; + } + } - offset.x = controller; - offset.y += SQUARE_SIZE; - } + offset.x = controller; + offset.y += SQUARE_SIZE; + } - rl::drawText("INCOMING:", offset.x, offset.y - 100, 10, rl::GRAY); - rl::drawText(rl::textFormat("LINES: %04i", lines), offset.x, offset.y + 20, 10, rl::GRAY); + rl::draw_text("INCOMING:", offset.x, offset.y - 100, 10, rl::GRAY); + rl::draw_text(rl::text_format("LINES: %04i", lines), offset.x, offset.y + 20, 10, rl::GRAY); - if (pause) - { - rl::drawText("GAME PAUSED", SCREEN_WIDTH / 2 - rl::measureText("GAME PAUSED", 40)/2, SCREEN_HEIGHT/2 - 40, 40, rl::GRAY); - } + if (pause) + { + rl::draw_text("GAME PAUSED", SCREEN_WIDTH / 2 - rl::measure_text("GAME PAUSED", 40)/2, SCREEN_HEIGHT/2 - 40, 40, rl::GRAY); + } } // Unload game variables fn void unload_game() { - // TODO: Unload all dynamic loaded data (textures, sounds, models...) + // TODO: Unload all dynamic loaded data (textures, sounds, models...) } // Update and Draw (one frame) fn void update_draw_frame() { - update_game(); - draw_game(); + update_game(); + draw_game(); } //-------------------------------------------------------------------------------------- @@ -377,415 +372,384 @@ fn void update_draw_frame() //-------------------------------------------------------------------------------------- fn bool create_piece() { - piece_position_x = (int)((GRID_HORIZONTAL_SIZE - 4)/2); - piece_position_y = 0; + piece_position_x = (int)((GRID_HORIZONTAL_SIZE - 4)/2); + piece_position_y = 0; - // If the game is starting and you are going to create the first piece, we create an extra one - if (begin_play) - { - get_random_piece(); - begin_play = false; - } + // If the game is starting and you are going to create the first piece, we create an extra one + if (begin_play) + { + get_random_piece(); + begin_play = false; + } - // We assign the incoming piece to the actual piece - for (int i = 0; i < 4; i++) - { - for (int j = 0; j< 4; j++) - { - piece[i][j] = incoming_piece[i][j]; - } - } + // We assign the incoming piece to the actual piece + for (int i = 0; i < 4; i++) + { + for (int j = 0; j< 4; j++) + { + piece[i][j] = incoming_piece[i][j]; + } + } - // We assign a random piece to the incoming one - get_random_piece(); + // We assign a random piece to the incoming one + get_random_piece(); - // Assign the piece to the grid - for (int i = piece_position_x; i < piece_position_x + 4; i++) - { - for (int j = 0; j < 4; j++) - { - if (piece[i - (int)piece_position_x][j] == MOVING) grid[i][j] = MOVING; - } - } + // Assign the piece to the grid + for (int i = piece_position_x; i < piece_position_x + 4; i++) + { + for (int j = 0; j < 4; j++) + { + if (piece[i - (int)piece_position_x][j] == MOVING) grid[i][j] = MOVING; + } + } - return true; + return true; } fn void get_random_piece() { - int random = rl::getRandomValue(0, 6); + int random = rl::get_random_value(0, 6); - for (int i = 0; i < 4; i++) - { - for (int j = 0; j < 4; j++) - { - incoming_piece[i][j] = EMPTY; - } - } + for (int i = 0; i < 4; i++) + { + for (int j = 0; j < 4; j++) + { + incoming_piece[i][j] = EMPTY; + } + } - switch (random) - { - case 0: - incoming_piece[1][1] = MOVING; - incoming_piece[2][1] = MOVING; - incoming_piece[1][2] = MOVING; - incoming_piece[2][2] = MOVING; //Cube - case 1: - incoming_piece[1][0] = MOVING; - incoming_piece[1][1] = MOVING; - incoming_piece[1][2] = MOVING; - incoming_piece[2][2] = MOVING; //L - case 2: - incoming_piece[1][2] = MOVING; - incoming_piece[2][0] = MOVING; - incoming_piece[2][1] = MOVING; - incoming_piece[2][2] = MOVING; //L inversa - case 3: - incoming_piece[0][1] = MOVING; - incoming_piece[1][1] = MOVING; - incoming_piece[2][1] = MOVING; - incoming_piece[3][1] = MOVING; //Recta - case 4: - incoming_piece[1][0] = MOVING; - incoming_piece[1][1] = MOVING; - incoming_piece[1][2] = MOVING; - incoming_piece[2][1] = MOVING; //Creu tallada - case 5: - incoming_piece[1][1] = MOVING; - incoming_piece[2][1] = MOVING; - incoming_piece[2][2] = MOVING; - incoming_piece[3][2] = MOVING; //S - case 6: - incoming_piece[1][2] = MOVING; - incoming_piece[2][2] = MOVING; - incoming_piece[2][1] = MOVING; - incoming_piece[3][1] = MOVING; //S inversa - default: - unreachable(); - } + switch (random) + { + case 0: + incoming_piece[1][1] = MOVING; + incoming_piece[2][1] = MOVING; + incoming_piece[1][2] = MOVING; + incoming_piece[2][2] = MOVING; //Cube + case 1: + incoming_piece[1][0] = MOVING; + incoming_piece[1][1] = MOVING; + incoming_piece[1][2] = MOVING; + incoming_piece[2][2] = MOVING; //L + case 2: + incoming_piece[1][2] = MOVING; + incoming_piece[2][0] = MOVING; + incoming_piece[2][1] = MOVING; + incoming_piece[2][2] = MOVING; //L inversa + case 3: + incoming_piece[0][1] = MOVING; + incoming_piece[1][1] = MOVING; + incoming_piece[2][1] = MOVING; + incoming_piece[3][1] = MOVING; //Recta + case 4: + incoming_piece[1][0] = MOVING; + incoming_piece[1][1] = MOVING; + incoming_piece[1][2] = MOVING; + incoming_piece[2][1] = MOVING; //Creu tallada + case 5: + incoming_piece[1][1] = MOVING; + incoming_piece[2][1] = MOVING; + incoming_piece[2][2] = MOVING; + incoming_piece[3][2] = MOVING; //S + case 6: + incoming_piece[1][2] = MOVING; + incoming_piece[2][2] = MOVING; + incoming_piece[2][1] = MOVING; + incoming_piece[3][1] = MOVING; //S inversa + default: + unreachable(); + } } fn void resolve_falling_movement(bool* detection_ref, bool* piece_active_ref) { - // If we finished moving this piece, we stop it - if (*detection_ref) - { - for (int j = GRID_VERTICAL_SIZE - 2; j >= 0; j--) - { - for (int i = 1; i < GRID_HORIZONTAL_SIZE - 1; i++) - { - if (grid[i][j] == MOVING) - { - grid[i][j] = FULL; - *detection_ref = false; - *piece_active_ref = false; - } - } - } - } - else // We move down the piece - { - for (int j = GRID_VERTICAL_SIZE - 2; j >= 0; j--) - { - for (int i = 1; i < GRID_HORIZONTAL_SIZE - 1; i++) - { - if (grid[i][j] == MOVING) - { - grid[i][j+1] = MOVING; - grid[i][j] = EMPTY; - } - } - } + // If we finished moving this piece, we stop it + if (*detection_ref) + { + for (int j = GRID_VERTICAL_SIZE - 2; j >= 0; j--) + { + for (int i = 1; i < GRID_HORIZONTAL_SIZE - 1; i++) + { + if (grid[i][j] == MOVING) + { + grid[i][j] = FULL; + *detection_ref = false; + *piece_active_ref = false; + } + } + } + } + else // We move down the piece + { + for (int j = GRID_VERTICAL_SIZE - 2; j >= 0; j--) + { + for (int i = 1; i < GRID_HORIZONTAL_SIZE - 1; i++) + { + if (grid[i][j] == MOVING) + { + grid[i][j+1] = MOVING; + grid[i][j] = EMPTY; + } + } + } - piece_position_y++; - } + piece_position_y++; + } } fn bool resolve_lateral_movement() { - bool collision = false; - - // Piece movement - if (rl::isKeyDown(rl::KEY_LEFT)) // Move left - { - // Check if is possible to move to left - for (int j = GRID_VERTICAL_SIZE - 2; j >= 0; j--) - { - for (int i = 1; i < GRID_HORIZONTAL_SIZE - 1; i++) - { - if (grid[i][j] == MOVING) - { - // Check if we are touching the left wall or we have a full square at the left - if ((i-1 == 0) || (grid[i-1][j] == FULL)) collision = true; - } - } - } - - // If able, move left - if (!collision) - { - for (int j = GRID_VERTICAL_SIZE - 2; j >= 0; j--) - { - for (int i = 1; i < GRID_HORIZONTAL_SIZE - 1; i++) // We check the matrix from left to right - { - // Move everything to the left - if (grid[i][j] == GridSquare.MOVING) - { - grid[i-1][j] = MOVING; - grid[i][j] = EMPTY; - } - } - } - - piece_position_x--; - } - } - else if (rl::isKeyDown(rl::KEY_RIGHT)) // Move right - { - // Check if is possible to move to right - for (int j = GRID_VERTICAL_SIZE - 2; j >= 0; j--) - { - for (int i = 1; i < GRID_HORIZONTAL_SIZE - 1; i++) - { - if (grid[i][j] == GridSquare.MOVING) - { - // Check if we are touching the right wall or we have a full square at the right - if ((i+1 == GRID_HORIZONTAL_SIZE - 1) || (grid[i+1][j] == GridSquare.FULL)) - { - collision = true; - - } - } - } - } - - // If able move right - if (!collision) - { - for (int j = GRID_VERTICAL_SIZE - 2; j >= 0; j--) - { - for (int i = GRID_HORIZONTAL_SIZE - 1; i >= 1; i--) // We check the matrix from right to left - { - // Move everything to the right - if (grid[i][j] == GridSquare.MOVING) - { - grid[i+1][j] = MOVING; - grid[i][j] = EMPTY; - } - } - } - - piece_position_x++; - } - } - - return collision; + // Piece movement + switch + { + case rl::is_key_down(LEFT): // Move left + // Check if is possible to move to left + for (int j = GRID_VERTICAL_SIZE - 2; j >= 0; j--) + { + for (int i = 1; i < GRID_HORIZONTAL_SIZE - 1; i++) + { + if (grid[i][j] == MOVING) + { + // Check if we are touching the left wall or we have a full square at the left + if ((i - 1 == 0) || (grid[i - 1][j] == FULL)) return true; + } + } + } + // If able, move left + for (int j = GRID_VERTICAL_SIZE - 2; j >= 0; j--) + { + for (int i = 1; i < GRID_HORIZONTAL_SIZE - 1; i++) // We check the matrix from left to right + { + // Move everything to the left + if (grid[i][j] == GridSquare.MOVING) + { + grid[i - 1][j] = MOVING; + grid[i][j] = EMPTY; + } + } + } + piece_position_x--; + return false; + case rl::is_key_down(RIGHT): // Move right + // Check if is possible to move to right + for (int j = GRID_VERTICAL_SIZE - 2; j >= 0; j--) + { + for (int i = 1; i < GRID_HORIZONTAL_SIZE - 1; i++) + { + if (grid[i][j] == GridSquare.MOVING) + { + // Check if we are touching the right wall or we have a full square at the right + if ((i + 1 == GRID_HORIZONTAL_SIZE - 1) || (grid[i + 1][j] == GridSquare.FULL)) return true; + } + } + } + for (int j = GRID_VERTICAL_SIZE - 2; j >= 0; j--) + { + for (int i = GRID_HORIZONTAL_SIZE - 1; i >= 1; i--) // We check the matrix from right to left + { + // Move everything to the right + if (grid[i][j] == GridSquare.MOVING) + { + grid[i + 1][j] = MOVING; + grid[i][j] = EMPTY; + } + } + } + piece_position_x++; + return false; + } + return false; } fn bool resolve_turn_movement() { - // Input for turning the piece - if (rl::isKeyDown(rl::KEY_UP)) - { - GridSquare aux; - bool checker = false; + // Input for turning the piece + if (!rl::is_key_down(UP)) return false; + + // Check all turning possibilities + do + { + if (grid[piece_position_x + 3][piece_position_y] == MOVING + && grid[piece_position_x][piece_position_y] != EMPTY + && grid[piece_position_x][piece_position_y] != MOVING) break; + + if (grid[piece_position_x + 3][piece_position_y + 3] == MOVING + && grid[piece_position_x + 3][piece_position_y] != EMPTY + && grid[piece_position_x + 3][piece_position_y] != MOVING) break; + + if (grid[piece_position_x][piece_position_y + 3] == MOVING + && grid[piece_position_x + 3][piece_position_y + 3] != EMPTY + && grid[piece_position_x + 3][piece_position_y + 3] != MOVING) break; + + if (grid[piece_position_x][piece_position_y] == MOVING + && grid[piece_position_x][piece_position_y + 3] != EMPTY + && grid[piece_position_x][piece_position_y + 3] != MOVING) break; + + if (grid[piece_position_x + 1][piece_position_y] == MOVING + && grid[piece_position_x][piece_position_y + 2] != EMPTY + && grid[piece_position_x][piece_position_y + 2] != MOVING) break; + + if (grid[piece_position_x + 3][piece_position_y + 1] == MOVING + && grid[piece_position_x + 1][piece_position_y] != EMPTY + && grid[piece_position_x + 1][piece_position_y] != MOVING) break; + + if (grid[piece_position_x + 2][piece_position_y + 3] == MOVING + && grid[piece_position_x + 3][piece_position_y + 1] != EMPTY + && grid[piece_position_x + 3][piece_position_y + 1] != MOVING) break; + + if (grid[piece_position_x][piece_position_y + 2] == MOVING + && grid[piece_position_x + 2][piece_position_y + 3] != EMPTY + && grid[piece_position_x + 2][piece_position_y + 3] != MOVING) break; + + if (grid[piece_position_x + 2][piece_position_y] == MOVING + && grid[piece_position_x][piece_position_y + 1] != EMPTY + && grid[piece_position_x][piece_position_y + 1] != MOVING) break; + + if (grid[piece_position_x + 3][piece_position_y + 2] == MOVING + && grid[piece_position_x + 2][piece_position_y] != EMPTY + && grid[piece_position_x + 2][piece_position_y] != MOVING) break; + + if (grid[piece_position_x + 1][piece_position_y + 3] == MOVING + && grid[piece_position_x + 3][piece_position_y + 2] != EMPTY + && grid[piece_position_x + 3][piece_position_y + 2] != MOVING) break; + + if (grid[piece_position_x][piece_position_y + 1] == MOVING + && grid[piece_position_x + 1][piece_position_y + 3] != EMPTY + && grid[piece_position_x + 1][piece_position_y + 3] != MOVING) break; + + if (grid[piece_position_x + 1][piece_position_y + 1] == MOVING + && grid[piece_position_x + 1][piece_position_y + 2] != EMPTY + && grid[piece_position_x + 1][piece_position_y + 2] != MOVING) break; + + if (grid[piece_position_x + 2][piece_position_y + 1] == MOVING + && grid[piece_position_x + 1][piece_position_y + 1] != EMPTY + && grid[piece_position_x + 1][piece_position_y + 1] != MOVING) break; + + if (grid[piece_position_x + 2][piece_position_y + 2] == MOVING + && grid[piece_position_x + 2][piece_position_y + 1] != EMPTY + && grid[piece_position_x + 2][piece_position_y + 1] != MOVING) break; + + if (grid[piece_position_x + 1][piece_position_y + 2] == MOVING + && grid[piece_position_x + 2][piece_position_y + 2] != EMPTY + && grid[piece_position_x + 2][piece_position_y + 2] != MOVING) break; - // Check all turning possibilities - if ((grid[piece_position_x + 3][piece_position_y] == GridSquare.MOVING) && - (grid[piece_position_x][piece_position_y] != GridSquare.EMPTY) && - (grid[piece_position_x][piece_position_y] != GridSquare.MOVING)) checker = true; + GridSquare aux = piece[0][0]; + piece[0][0] = piece[3][0]; + piece[3][0] = piece[3][3]; + piece[3][3] = piece[0][3]; + piece[0][3] = aux; - if ((grid[piece_position_x + 3][piece_position_y + 3] == GridSquare.MOVING) && - (grid[piece_position_x + 3][piece_position_y] != GridSquare.EMPTY) && - (grid[piece_position_x + 3][piece_position_y] != GridSquare.MOVING)) checker = true; + aux = piece[1][0]; + piece[1][0] = piece[3][1]; + piece[3][1] = piece[2][3]; + piece[2][3] = piece[0][2]; + piece[0][2] = aux; - if ((grid[piece_position_x][piece_position_y + 3] == GridSquare.MOVING) && - (grid[piece_position_x + 3][piece_position_y + 3] != GridSquare.EMPTY) && - (grid[piece_position_x + 3][piece_position_y + 3] != GridSquare.MOVING)) checker = true; + aux = piece[2][0]; + piece[2][0] = piece[3][2]; + piece[3][2] = piece[1][3]; + piece[1][3] = piece[0][1]; + piece[0][1] = aux; - if ((grid[piece_position_x][piece_position_y] == GridSquare.MOVING) && - (grid[piece_position_x][piece_position_y + 3] != GridSquare.EMPTY) && - (grid[piece_position_x][piece_position_y + 3] != GridSquare.MOVING)) checker = true; + aux = piece[1][1]; + piece[1][1] = piece[2][1]; + piece[2][1] = piece[2][2]; + piece[2][2] = piece[1][2]; + piece[1][2] = aux; + }; - if ((grid[piece_position_x + 1][piece_position_y] == GridSquare.MOVING) && - (grid[piece_position_x][piece_position_y + 2] != GridSquare.EMPTY) && - (grid[piece_position_x][piece_position_y + 2] != GridSquare.MOVING)) checker = true; + for (int j = GRID_VERTICAL_SIZE - 2; j >= 0; j--) + { + for (int i = 1; i < GRID_HORIZONTAL_SIZE - 1; i++) + { + if (grid[i][j] == MOVING) grid[i][j] = EMPTY; + } + } - if ((grid[piece_position_x + 3][piece_position_y + 1] == GridSquare.MOVING) && - (grid[piece_position_x + 1][piece_position_y] != GridSquare.EMPTY) && - (grid[piece_position_x + 1][piece_position_y] != GridSquare.MOVING)) checker = true; - - if ((grid[piece_position_x + 2][piece_position_y + 3] == GridSquare.MOVING) && - (grid[piece_position_x + 3][piece_position_y + 1] != GridSquare.EMPTY) && - (grid[piece_position_x + 3][piece_position_y + 1] != GridSquare.MOVING)) checker = true; - - if ((grid[piece_position_x][piece_position_y + 2] == GridSquare.MOVING) && - (grid[piece_position_x + 2][piece_position_y + 3] != GridSquare.EMPTY) && - (grid[piece_position_x + 2][piece_position_y + 3] != GridSquare.MOVING)) checker = true; - - if ((grid[piece_position_x + 2][piece_position_y] == GridSquare.MOVING) && - (grid[piece_position_x][piece_position_y + 1] != GridSquare.EMPTY) && - (grid[piece_position_x][piece_position_y + 1] != GridSquare.MOVING)) checker = true; - - if ((grid[piece_position_x + 3][piece_position_y + 2] == GridSquare.MOVING) && - (grid[piece_position_x + 2][piece_position_y] != GridSquare.EMPTY) && - (grid[piece_position_x + 2][piece_position_y] != GridSquare.MOVING)) checker = true; - - if ((grid[piece_position_x + 1][piece_position_y + 3] == GridSquare.MOVING) && - (grid[piece_position_x + 3][piece_position_y + 2] != GridSquare.EMPTY) && - (grid[piece_position_x + 3][piece_position_y + 2] != GridSquare.MOVING)) checker = true; - - if ((grid[piece_position_x][piece_position_y + 1] == GridSquare.MOVING) && - (grid[piece_position_x + 1][piece_position_y + 3] != GridSquare.EMPTY) && - (grid[piece_position_x + 1][piece_position_y + 3] != GridSquare.MOVING)) checker = true; - - if ((grid[piece_position_x + 1][piece_position_y + 1] == GridSquare.MOVING) && - (grid[piece_position_x + 1][piece_position_y + 2] != GridSquare.EMPTY) && - (grid[piece_position_x + 1][piece_position_y + 2] != GridSquare.MOVING)) checker = true; - - if ((grid[piece_position_x + 2][piece_position_y + 1] == GridSquare.MOVING) && - (grid[piece_position_x + 1][piece_position_y + 1] != GridSquare.EMPTY) && - (grid[piece_position_x + 1][piece_position_y + 1] != GridSquare.MOVING)) checker = true; - - if ((grid[piece_position_x + 2][piece_position_y + 2] == GridSquare.MOVING) && - (grid[piece_position_x + 2][piece_position_y + 1] != GridSquare.EMPTY) && - (grid[piece_position_x + 2][piece_position_y + 1] != GridSquare.MOVING)) checker = true; - - if ((grid[piece_position_x + 1][piece_position_y + 2] == GridSquare.MOVING) && - (grid[piece_position_x + 2][piece_position_y + 2] != GridSquare.EMPTY) && - (grid[piece_position_x + 2][piece_position_y + 2] != GridSquare.MOVING)) checker = true; - - if (!checker) - { - aux = piece[0][0]; - piece[0][0] = piece[3][0]; - piece[3][0] = piece[3][3]; - piece[3][3] = piece[0][3]; - piece[0][3] = aux; - - aux = piece[1][0]; - piece[1][0] = piece[3][1]; - piece[3][1] = piece[2][3]; - piece[2][3] = piece[0][2]; - piece[0][2] = aux; - - aux = piece[2][0]; - piece[2][0] = piece[3][2]; - piece[3][2] = piece[1][3]; - piece[1][3] = piece[0][1]; - piece[0][1] = aux; - - aux = piece[1][1]; - piece[1][1] = piece[2][1]; - piece[2][1] = piece[2][2]; - piece[2][2] = piece[1][2]; - piece[1][2] = aux; - } - - for (int j = GRID_VERTICAL_SIZE - 2; j >= 0; j--) - { - for (int i = 1; i < GRID_HORIZONTAL_SIZE - 1; i++) - { - if (grid[i][j] == GridSquare.MOVING) - { - grid[i][j] = EMPTY; - } - } - } - - for (int i = piece_position_x; i < piece_position_x + 4; i++) - { - for (int j = piece_position_y; j < piece_position_y + 4; j++) - { - if (piece[i - piece_position_x][j - piece_position_y] == GridSquare.MOVING) - { - grid[i][j] = MOVING; - } - } - } - - return true; - } - - return false; + for (int i = piece_position_x; i < piece_position_x + 4; i++) + { + for (int j = piece_position_y; j < piece_position_y + 4; j++) + { + if (piece[i - piece_position_x][j - piece_position_y] == MOVING) grid[i][j] = MOVING; + } + } + return true; } fn bool check_detection() { - for (int j = GRID_VERTICAL_SIZE - 2; j >= 0; j--) - { - for (int i = 1; i < GRID_HORIZONTAL_SIZE - 1; i++) - { - if ((grid[i][j] == GridSquare.MOVING) && ((grid[i][j+1] == GridSquare.FULL) - || (grid[i][j+1] == GridSquare.BLOCK))) return true; - } - } - return false; + for (int j = GRID_VERTICAL_SIZE - 2; j >= 0; j--) + { + for (int i = 1; i < GRID_HORIZONTAL_SIZE - 1; i++) + { + if (grid[i][j] != MOVING) continue; + if (grid[i][j + 1] == FULL || grid[i][j + 1] == BLOCK) return true; + } + } + return false; } fn void check_completion(bool *line_to_delete_ref) { - int calculator = 0; + int calculator = 0; + for (int j = GRID_VERTICAL_SIZE - 2; j >= 0; j--) + { + calculator = 0; + for (int i = 1; i < GRID_HORIZONTAL_SIZE - 1; i++) + { + // Count each square of the line + if (grid[i][j] == FULL) + { + calculator++; + } - for (int j = GRID_VERTICAL_SIZE - 2; j >= 0; j--) - { - calculator = 0; - for (int i = 1; i < GRID_HORIZONTAL_SIZE - 1; i++) - { - // Count each square of the line - if (grid[i][j] == GridSquare.FULL) - { - calculator++; - } + // Check if we completed the whole line + if (calculator == GRID_HORIZONTAL_SIZE - 2) + { + *line_to_delete_ref = true; + calculator = 0; + // points++; - // Check if we completed the whole line - if (calculator == GRID_HORIZONTAL_SIZE - 2) - { - *line_to_delete_ref = true; - calculator = 0; - // points++; - - // Mark the completed line - for (int z = 1; z < GRID_HORIZONTAL_SIZE - 1; z++) - { - grid[z][j] = FADING; - } - } - } - } + // Mark the completed line + for (int z = 1; z < GRID_HORIZONTAL_SIZE - 1; z++) + { + grid[z][j] = FADING; + } + } + } + } } fn int delete_complete_lines() { int lines_to_erase = 0; - // Erase the completed line - for (int j = GRID_VERTICAL_SIZE - 2; j >= 0; j--) - { - while (grid[1][j] == GridSquare.FADING) - { - lines_to_erase++; - for (int i = 1; i < GRID_HORIZONTAL_SIZE - 1; i++) - { - grid[i][j] = GridSquare.EMPTY; - } + // Erase the completed line + for (int j = GRID_VERTICAL_SIZE - 2; j >= 0; j--) + { + while (grid[1][j] == FADING) + { + lines_to_erase++; + for (int i = 1; i < GRID_HORIZONTAL_SIZE - 1; i++) + { + grid[i][j] = EMPTY; + } - for (int j2 = j-1; j2 >= 0; j2--) - { - for (int i2 = 1; i2 < GRID_HORIZONTAL_SIZE - 1; i2++) - { - switch (grid[i2][j2]) - { - case FULL: - grid[i2][j2+1] = GridSquare.FULL; - grid[i2][j2] = GridSquare.EMPTY; - case FADING: - grid[i2][j2+1] = GridSquare.FADING; - grid[i2][j2] = GridSquare.EMPTY; - default: - } - } - } - } - } - return lines_to_erase; + for (int j2 = j-1; j2 >= 0; j2--) + { + for (int i2 = 1; i2 < GRID_HORIZONTAL_SIZE - 1; i2++) + { + switch (grid[i2][j2]) + { + case FULL: + grid[i2][j2 + 1] = FULL; + grid[i2][j2] = EMPTY; + case FADING: + grid[i2][j2 + 1] = FADING; + grid[i2][j2] = EMPTY; + default: + } + } + } + } + } + return lines_to_erase; } \ No newline at end of file