add arkanoid template
This commit is contained in:
parent
62caa94e23
commit
7d2a8b7dde
Binary file not shown.
After Width: | Height: | Size: 66 KiB |
|
@ -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
|
|
@ -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 <raylib.h>
|
||||||
|
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <time.h>
|
||||||
|
#include <math.h>
|
||||||
|
|
||||||
|
#if defined(PLATFORM_WEB)
|
||||||
|
#include <emscripten/emscripten.h>
|
||||||
|
#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();
|
||||||
|
}
|
Binary file not shown.
After Width: | Height: | Size: 66 KiB |
|
@ -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
|
|
@ -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 <raylib.h>
|
||||||
|
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <time.h>
|
||||||
|
#include <math.h>
|
||||||
|
|
||||||
|
#if defined(PLATFORM_WEB)
|
||||||
|
#include <emscripten/emscripten.h>
|
||||||
|
#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();
|
||||||
|
}
|
Loading…
Reference in New Issue