From 7d2a8b7dde67dee246c496f44ef65dedd71b0fca Mon Sep 17 00:00:00 2001 From: Roy Qu Date: Mon, 25 Jul 2022 16:13:44 +0800 Subject: [PATCH] add arkanoid template --- linux/templates/raylib_arkanoid.ico | Bin 0 -> 67646 bytes linux/templates/raylib_arkanoid.template | 20 ++ linux/templates/raylib_arkanoid_c.txt | 324 +++++++++++++++++++++ windows/templates/raylib_arkanoid.ico | Bin 0 -> 67646 bytes windows/templates/raylib_arkanoid.template | 20 ++ windows/templates/raylib_arkanoid_c.txt | 324 +++++++++++++++++++++ 6 files changed, 688 insertions(+) create mode 100644 linux/templates/raylib_arkanoid.ico create mode 100644 linux/templates/raylib_arkanoid.template create mode 100644 linux/templates/raylib_arkanoid_c.txt create mode 100644 windows/templates/raylib_arkanoid.ico create mode 100644 windows/templates/raylib_arkanoid.template create mode 100644 windows/templates/raylib_arkanoid_c.txt diff --git a/linux/templates/raylib_arkanoid.ico b/linux/templates/raylib_arkanoid.ico new file mode 100644 index 0000000000000000000000000000000000000000..be05b231dab1f3114b6fe3270149cc8bdc0b203b GIT binary patch literal 67646 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 literal 0 HcmV?d00001 diff --git a/linux/templates/raylib_arkanoid.template b/linux/templates/raylib_arkanoid.template new file mode 100644 index 00000000..ec3658ea --- /dev/null +++ b/linux/templates/raylib_arkanoid.template @@ -0,0 +1,20 @@ +[Template] +ver=2 +Name=arkanoid +Name[zh_CN]=打砖块 +Icon=raylib_arkanoid.ico +Description=arkanoid game using raylib ( https://raylib.com ) +Description[zh_CN]=经典的打砖块游戏(基于raylib) ( https://raylib.com ) +Category=Game +Category[zh_CN]=游戏 + +[Unit0] +CName=main.c +C=raylib_arkanoid_c.txt + +[Project] +UnitCount=1 +Type=1 +IsCpp=0 +linker=-lraylib -lGL -lm -lpthread -ldl -lrt -lX11 +ExecEncoding=UTF-8 diff --git a/linux/templates/raylib_arkanoid_c.txt b/linux/templates/raylib_arkanoid_c.txt new file mode 100644 index 00000000..ae906423 --- /dev/null +++ b/linux/templates/raylib_arkanoid_c.txt @@ -0,0 +1,324 @@ +/******************************************************************************************* +* +* raylib - classic game: arkanoid +* +* Sample game developed by Marc Palau and Ramon Santamaria +* +* This game has been created using raylib v1.3 (www.raylib.com) +* raylib is licensed under an unmodified zlib/libpng license (View raylib.h for details) +* +* Copyright (c) 2015 Ramon Santamaria (@raysan5) +* +* Icon from https://www.flaticon.com/free-icon/arkanoid_2927802 +********************************************************************************************/ + +#include + +#include +#include +#include +#include + +#if defined(PLATFORM_WEB) +#include +#endif + +//---------------------------------------------------------------------------------- +// Some Defines +//---------------------------------------------------------------------------------- +#define PLAYER_MAX_LIFE 5 +#define LINES_OF_BRICKS 5 +#define BRICKS_PER_LINE 20 + +//---------------------------------------------------------------------------------- +// Types and Structures Definition +//---------------------------------------------------------------------------------- +typedef enum GameScreen { LOGO, TITLE, GAMEPLAY, ENDING } GameScreen; + +typedef struct Player { + Vector2 position; + Vector2 size; + int life; +} Player; + +typedef struct Ball { + Vector2 position; + Vector2 speed; + int radius; + bool active; +} Ball; + +typedef struct Brick { + Vector2 position; + bool active; +} Brick; + +//------------------------------------------------------------------------------------ +// Global Variables Declaration +//------------------------------------------------------------------------------------ +static const int screenWidth = 800; +static const int screenHeight = 450; + +static bool gameOver = false; +static bool pause = false; + +static Player player = { 0 }; +static Ball ball = { 0 }; +static Brick brick[LINES_OF_BRICKS][BRICKS_PER_LINE] = { 0 }; +static Vector2 brickSize = { 0 }; + +//------------------------------------------------------------------------------------ +// Module Functions Declaration (local) +//------------------------------------------------------------------------------------ +static void InitGame(void); // Initialize game +static void UpdateGame(void); // Update game (one frame) +static void DrawGame(void); // Draw game (one frame) +static void UnloadGame(void); // Unload game +static void UpdateDrawFrame(void); // Update and Draw (one frame) + +//------------------------------------------------------------------------------------ +// Program main entry point +//------------------------------------------------------------------------------------ +int main(void) +{ + // Initialization (Note windowTitle is unused on Android) + //--------------------------------------------------------- + InitWindow(screenWidth, screenHeight, "classic game: arkanoid"); + + InitGame(); + +#if defined(PLATFORM_WEB) + emscripten_set_main_loop(UpdateDrawFrame, 60, 1); +#else + SetTargetFPS(60); + //-------------------------------------------------------------------------------------- + + // Main game loop + while (!WindowShouldClose()) // Detect window close button or ESC key + { + // Update and Draw + //---------------------------------------------------------------------------------- + UpdateDrawFrame(); + //---------------------------------------------------------------------------------- + } +#endif + // De-Initialization + //-------------------------------------------------------------------------------------- + UnloadGame(); // Unload loaded data (textures, sounds, models...) + + CloseWindow(); // Close window and OpenGL context + //-------------------------------------------------------------------------------------- + + return 0; +} + +//------------------------------------------------------------------------------------ +// Module Functions Definitions (local) +//------------------------------------------------------------------------------------ + +// Initialize game variables +void InitGame(void) +{ + brickSize = (Vector2){ GetScreenWidth()/BRICKS_PER_LINE, 40 }; + + // Initialize player + player.position = (Vector2){ screenWidth/2, screenHeight*7/8 }; + player.size = (Vector2){ screenWidth/10, 20 }; + player.life = PLAYER_MAX_LIFE; + + // Initialize ball + ball.position = (Vector2){ screenWidth/2, screenHeight*7/8 - 30 }; + ball.speed = (Vector2){ 0, 0 }; + ball.radius = 7; + ball.active = false; + + // Initialize bricks + int initialDownPosition = 50; + + for (int i = 0; i < LINES_OF_BRICKS; i++) + { + for (int j = 0; j < BRICKS_PER_LINE; j++) + { + brick[i][j].position = (Vector2){ j*brickSize.x + brickSize.x/2, i*brickSize.y + initialDownPosition }; + brick[i][j].active = true; + } + } +} + +// Update game (one frame) +void UpdateGame(void) +{ + if (!gameOver) + { + if (IsKeyPressed('P')) pause = !pause; + + if (!pause) + { + // Player movement logic + if (IsKeyDown(KEY_LEFT)) player.position.x -= 5; + if ((player.position.x - player.size.x/2) <= 0) player.position.x = player.size.x/2; + if (IsKeyDown(KEY_RIGHT)) player.position.x += 5; + if ((player.position.x + player.size.x/2) >= screenWidth) player.position.x = screenWidth - player.size.x/2; + + // Ball launching logic + if (!ball.active) + { + if (IsKeyPressed(KEY_SPACE)) + { + ball.active = true; + ball.speed = (Vector2){ 0, -5 }; + } + } + + // Ball movement logic + if (ball.active) + { + ball.position.x += ball.speed.x; + ball.position.y += ball.speed.y; + } + else + { + ball.position = (Vector2){ player.position.x, screenHeight*7/8 - 30 }; + } + + // Collision logic: ball vs walls + if (((ball.position.x + ball.radius) >= screenWidth) || ((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) >= screenHeight) + { + ball.speed = (Vector2){ 0, 0 }; + ball.active = false; + + player.life--; + } + + // Collision logic: ball vs player + if (CheckCollisionCircleRec(ball.position, ball.radius, + (Rectangle){ 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; + } + } + + // 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 + brickSize.y/2)) && + ((ball.position.y - ball.radius) > (brick[i][j].position.y + brickSize.y/2 + ball.speed.y)) && + ((fabs(ball.position.x - brick[i][j].position.x)) < (brickSize.x/2 + ball.radius*2/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 - brickSize.y/2)) && + ((ball.position.y + ball.radius) < (brick[i][j].position.y - brickSize.y/2 + ball.speed.y)) && + ((fabs(ball.position.x - brick[i][j].position.x)) < (brickSize.x/2 + ball.radius*2/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 - brickSize.x/2)) && + ((ball.position.x + ball.radius) < (brick[i][j].position.x - brickSize.x/2 + ball.speed.x)) && + ((fabs(ball.position.y - brick[i][j].position.y)) < (brickSize.y/2 + ball.radius*2/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 + brickSize.x/2)) && + ((ball.position.x - ball.radius) > (brick[i][j].position.x + brickSize.x/2 + ball.speed.x)) && + ((fabs(ball.position.y - brick[i][j].position.y)) < (brickSize.y/2 + ball.radius*2/3)) && (ball.speed.x < 0)) + { + brick[i][j].active = false; + ball.speed.x *= -1; + } + } + } + } + + // Game over logic + if (player.life <= 0) gameOver = true; + else + { + gameOver = true; + + for (int i = 0; i < LINES_OF_BRICKS; i++) + { + for (int j = 0; j < BRICKS_PER_LINE; j++) + { + if (brick[i][j].active) gameOver = false; + } + } + } + } + } + else + { + if (IsKeyPressed(KEY_ENTER)) + { + InitGame(); + gameOver = false; + } + } +} + +// Draw game (one frame) +void DrawGame(void) +{ + BeginDrawing(); + + ClearBackground(RAYWHITE); + + if (!gameOver) + { + // Draw player bar + DrawRectangle(player.position.x - player.size.x/2, player.position.y - player.size.y/2, player.size.x, player.size.y, BLACK); + + // Draw player lives + for (int i = 0; i < player.life; i++) DrawRectangle(20 + 40*i, screenHeight - 30, 35, 10, LIGHTGRAY); + + // Draw ball + DrawCircleV(ball.position, ball.radius, MAROON); + + // 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) DrawRectangle(brick[i][j].position.x - brickSize.x/2, brick[i][j].position.y - brickSize.y/2, brickSize.x, brickSize.y, GRAY); + else DrawRectangle(brick[i][j].position.x - brickSize.x/2, brick[i][j].position.y - brickSize.y/2, brickSize.x, brickSize.y, DARKGRAY); + } + } + } + + if (pause) DrawText("GAME PAUSED", screenWidth/2 - MeasureText("GAME PAUSED", 40)/2, screenHeight/2 - 40, 40, GRAY); + } + else DrawText("PRESS [ENTER] TO PLAY AGAIN", GetScreenWidth()/2 - MeasureText("PRESS [ENTER] TO PLAY AGAIN", 20)/2, GetScreenHeight()/2 - 50, 20, GRAY); + + EndDrawing(); +} + +// Unload game variables +void UnloadGame(void) +{ + // TODO: Unload all dynamic loaded data (textures, sounds, models...) +} + +// Update and Draw (one frame) +void UpdateDrawFrame(void) +{ + UpdateGame(); + DrawGame(); +} \ No newline at end of file diff --git a/windows/templates/raylib_arkanoid.ico b/windows/templates/raylib_arkanoid.ico new file mode 100644 index 0000000000000000000000000000000000000000..be05b231dab1f3114b6fe3270149cc8bdc0b203b GIT binary patch literal 67646 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 literal 0 HcmV?d00001 diff --git a/windows/templates/raylib_arkanoid.template b/windows/templates/raylib_arkanoid.template new file mode 100644 index 00000000..79c94263 --- /dev/null +++ b/windows/templates/raylib_arkanoid.template @@ -0,0 +1,20 @@ +[Template] +ver=2 +Name=arkanoid +Name[zh_CN]=打砖块 +Icon=raylib_arkanoid.ico +Description=arkanoid game using raylib ( https://raylib.com ) +Description[zh_CN]=经典的打砖块游戏(基于raylib) ( https://raylib.com ) +Category=Game +Category[zh_CN]=游戏 + +[Unit0] +CName=main.c +C=raylib_arkanoid_c.txt + +[Project] +UnitCount=1 +Type=1 +IsCpp=0 +linker=-lraylib -lopengl32 -lgdi32 -lwinmm +ExecEncoding=UTF-8 diff --git a/windows/templates/raylib_arkanoid_c.txt b/windows/templates/raylib_arkanoid_c.txt new file mode 100644 index 00000000..ae906423 --- /dev/null +++ b/windows/templates/raylib_arkanoid_c.txt @@ -0,0 +1,324 @@ +/******************************************************************************************* +* +* raylib - classic game: arkanoid +* +* Sample game developed by Marc Palau and Ramon Santamaria +* +* This game has been created using raylib v1.3 (www.raylib.com) +* raylib is licensed under an unmodified zlib/libpng license (View raylib.h for details) +* +* Copyright (c) 2015 Ramon Santamaria (@raysan5) +* +* Icon from https://www.flaticon.com/free-icon/arkanoid_2927802 +********************************************************************************************/ + +#include + +#include +#include +#include +#include + +#if defined(PLATFORM_WEB) +#include +#endif + +//---------------------------------------------------------------------------------- +// Some Defines +//---------------------------------------------------------------------------------- +#define PLAYER_MAX_LIFE 5 +#define LINES_OF_BRICKS 5 +#define BRICKS_PER_LINE 20 + +//---------------------------------------------------------------------------------- +// Types and Structures Definition +//---------------------------------------------------------------------------------- +typedef enum GameScreen { LOGO, TITLE, GAMEPLAY, ENDING } GameScreen; + +typedef struct Player { + Vector2 position; + Vector2 size; + int life; +} Player; + +typedef struct Ball { + Vector2 position; + Vector2 speed; + int radius; + bool active; +} Ball; + +typedef struct Brick { + Vector2 position; + bool active; +} Brick; + +//------------------------------------------------------------------------------------ +// Global Variables Declaration +//------------------------------------------------------------------------------------ +static const int screenWidth = 800; +static const int screenHeight = 450; + +static bool gameOver = false; +static bool pause = false; + +static Player player = { 0 }; +static Ball ball = { 0 }; +static Brick brick[LINES_OF_BRICKS][BRICKS_PER_LINE] = { 0 }; +static Vector2 brickSize = { 0 }; + +//------------------------------------------------------------------------------------ +// Module Functions Declaration (local) +//------------------------------------------------------------------------------------ +static void InitGame(void); // Initialize game +static void UpdateGame(void); // Update game (one frame) +static void DrawGame(void); // Draw game (one frame) +static void UnloadGame(void); // Unload game +static void UpdateDrawFrame(void); // Update and Draw (one frame) + +//------------------------------------------------------------------------------------ +// Program main entry point +//------------------------------------------------------------------------------------ +int main(void) +{ + // Initialization (Note windowTitle is unused on Android) + //--------------------------------------------------------- + InitWindow(screenWidth, screenHeight, "classic game: arkanoid"); + + InitGame(); + +#if defined(PLATFORM_WEB) + emscripten_set_main_loop(UpdateDrawFrame, 60, 1); +#else + SetTargetFPS(60); + //-------------------------------------------------------------------------------------- + + // Main game loop + while (!WindowShouldClose()) // Detect window close button or ESC key + { + // Update and Draw + //---------------------------------------------------------------------------------- + UpdateDrawFrame(); + //---------------------------------------------------------------------------------- + } +#endif + // De-Initialization + //-------------------------------------------------------------------------------------- + UnloadGame(); // Unload loaded data (textures, sounds, models...) + + CloseWindow(); // Close window and OpenGL context + //-------------------------------------------------------------------------------------- + + return 0; +} + +//------------------------------------------------------------------------------------ +// Module Functions Definitions (local) +//------------------------------------------------------------------------------------ + +// Initialize game variables +void InitGame(void) +{ + brickSize = (Vector2){ GetScreenWidth()/BRICKS_PER_LINE, 40 }; + + // Initialize player + player.position = (Vector2){ screenWidth/2, screenHeight*7/8 }; + player.size = (Vector2){ screenWidth/10, 20 }; + player.life = PLAYER_MAX_LIFE; + + // Initialize ball + ball.position = (Vector2){ screenWidth/2, screenHeight*7/8 - 30 }; + ball.speed = (Vector2){ 0, 0 }; + ball.radius = 7; + ball.active = false; + + // Initialize bricks + int initialDownPosition = 50; + + for (int i = 0; i < LINES_OF_BRICKS; i++) + { + for (int j = 0; j < BRICKS_PER_LINE; j++) + { + brick[i][j].position = (Vector2){ j*brickSize.x + brickSize.x/2, i*brickSize.y + initialDownPosition }; + brick[i][j].active = true; + } + } +} + +// Update game (one frame) +void UpdateGame(void) +{ + if (!gameOver) + { + if (IsKeyPressed('P')) pause = !pause; + + if (!pause) + { + // Player movement logic + if (IsKeyDown(KEY_LEFT)) player.position.x -= 5; + if ((player.position.x - player.size.x/2) <= 0) player.position.x = player.size.x/2; + if (IsKeyDown(KEY_RIGHT)) player.position.x += 5; + if ((player.position.x + player.size.x/2) >= screenWidth) player.position.x = screenWidth - player.size.x/2; + + // Ball launching logic + if (!ball.active) + { + if (IsKeyPressed(KEY_SPACE)) + { + ball.active = true; + ball.speed = (Vector2){ 0, -5 }; + } + } + + // Ball movement logic + if (ball.active) + { + ball.position.x += ball.speed.x; + ball.position.y += ball.speed.y; + } + else + { + ball.position = (Vector2){ player.position.x, screenHeight*7/8 - 30 }; + } + + // Collision logic: ball vs walls + if (((ball.position.x + ball.radius) >= screenWidth) || ((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) >= screenHeight) + { + ball.speed = (Vector2){ 0, 0 }; + ball.active = false; + + player.life--; + } + + // Collision logic: ball vs player + if (CheckCollisionCircleRec(ball.position, ball.radius, + (Rectangle){ 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; + } + } + + // 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 + brickSize.y/2)) && + ((ball.position.y - ball.radius) > (brick[i][j].position.y + brickSize.y/2 + ball.speed.y)) && + ((fabs(ball.position.x - brick[i][j].position.x)) < (brickSize.x/2 + ball.radius*2/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 - brickSize.y/2)) && + ((ball.position.y + ball.radius) < (brick[i][j].position.y - brickSize.y/2 + ball.speed.y)) && + ((fabs(ball.position.x - brick[i][j].position.x)) < (brickSize.x/2 + ball.radius*2/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 - brickSize.x/2)) && + ((ball.position.x + ball.radius) < (brick[i][j].position.x - brickSize.x/2 + ball.speed.x)) && + ((fabs(ball.position.y - brick[i][j].position.y)) < (brickSize.y/2 + ball.radius*2/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 + brickSize.x/2)) && + ((ball.position.x - ball.radius) > (brick[i][j].position.x + brickSize.x/2 + ball.speed.x)) && + ((fabs(ball.position.y - brick[i][j].position.y)) < (brickSize.y/2 + ball.radius*2/3)) && (ball.speed.x < 0)) + { + brick[i][j].active = false; + ball.speed.x *= -1; + } + } + } + } + + // Game over logic + if (player.life <= 0) gameOver = true; + else + { + gameOver = true; + + for (int i = 0; i < LINES_OF_BRICKS; i++) + { + for (int j = 0; j < BRICKS_PER_LINE; j++) + { + if (brick[i][j].active) gameOver = false; + } + } + } + } + } + else + { + if (IsKeyPressed(KEY_ENTER)) + { + InitGame(); + gameOver = false; + } + } +} + +// Draw game (one frame) +void DrawGame(void) +{ + BeginDrawing(); + + ClearBackground(RAYWHITE); + + if (!gameOver) + { + // Draw player bar + DrawRectangle(player.position.x - player.size.x/2, player.position.y - player.size.y/2, player.size.x, player.size.y, BLACK); + + // Draw player lives + for (int i = 0; i < player.life; i++) DrawRectangle(20 + 40*i, screenHeight - 30, 35, 10, LIGHTGRAY); + + // Draw ball + DrawCircleV(ball.position, ball.radius, MAROON); + + // 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) DrawRectangle(brick[i][j].position.x - brickSize.x/2, brick[i][j].position.y - brickSize.y/2, brickSize.x, brickSize.y, GRAY); + else DrawRectangle(brick[i][j].position.x - brickSize.x/2, brick[i][j].position.y - brickSize.y/2, brickSize.x, brickSize.y, DARKGRAY); + } + } + } + + if (pause) DrawText("GAME PAUSED", screenWidth/2 - MeasureText("GAME PAUSED", 40)/2, screenHeight/2 - 40, 40, GRAY); + } + else DrawText("PRESS [ENTER] TO PLAY AGAIN", GetScreenWidth()/2 - MeasureText("PRESS [ENTER] TO PLAY AGAIN", 20)/2, GetScreenHeight()/2 - 50, 20, GRAY); + + EndDrawing(); +} + +// Unload game variables +void UnloadGame(void) +{ + // TODO: Unload all dynamic loaded data (textures, sounds, models...) +} + +// Update and Draw (one frame) +void UpdateDrawFrame(void) +{ + UpdateGame(); + DrawGame(); +} \ No newline at end of file