Added movement, structs and organized the code a bit

master
Wynd 2025-08-29 22:42:52 +03:00
parent 95e5465308
commit 7b20ce4436
1 changed files with 106 additions and 23 deletions

129
main.c
View File

@ -2,22 +2,91 @@
#include "raymath.h" #include "raymath.h"
#include <math.h> #include <math.h>
#define VIRTUAL_WIDTH 800 #define VIRTUAL_WIDTH 640
#define VIRTUAL_HEIGHT 600 #define VIRTUAL_HEIGHT 360
#define FONT_SIZE 20 #define FONT_SIZE 30
#define PADDLE_SPEED 4.0 #define PADDLE_SPEED 4.0
#define PADDLE_WIDTH VIRTUAL_WIDTH / 8.0 #define PADDLE_WIDTH VIRTUAL_WIDTH / 8.0
#define PADDLE_HEIGHT VIRTUAL_HEIGHT / 30.0 #define PADDLE_HEIGHT VIRTUAL_HEIGHT / 30.0
#define BALL_RADIUS VIRTUAL_WIDTH / 80.0
#define BALL_BASE_SPEED 2.0f
#define BALL_MUL_SPEED 0.15f
typedef struct Player {
Rectangle shape;
int lives;
int score;
} Player;
typedef struct Ball {
Rectangle shape;
Vector2 velocity;
float velocityMultiplier;
bool firstBounce;
bool velocityApplied;
} Ball;
void MovePaddle(Player *player) {
Vector2 mouseDelta = GetMouseDelta();
player->shape.x = Clamp(player->shape.x + mouseDelta.x, 0, VIRTUAL_WIDTH - PADDLE_WIDTH);
}
void MoveBall(Ball *ball, Player *player) {
bool isColliding = CheckCollisionRecs(player->shape, ball->shape);
if (ball->shape.x - BALL_RADIUS < 0 || ball->shape.x + BALL_RADIUS > VIRTUAL_WIDTH) {
ball->velocity = Vector2Multiply(ball->velocity, (Vector2){-1.0f, 1.0f});
ball->velocityApplied = false;
} else if (ball->shape.y - BALL_RADIUS < 0) {
ball->velocity = Vector2Multiply(ball->velocity, (Vector2){1.0f, -1.0f});
ball->velocityApplied = false;
} else if (isColliding) {
ball->velocity = Vector2Multiply(ball->velocity, (Vector2){1.0f, -1.0f});
// Add speed multiplier every bounce to increase difficulty
if (!ball->velocityApplied) {
ball->velocityMultiplier = Clamp(ball->velocityMultiplier + BALL_MUL_SPEED, 1.0f, 4.0f);
// Safety so the ball doesn't get stuck inside the paddle from sides
ball->shape.y = player->shape.y - BALL_RADIUS;
ball->velocityApplied = true;
}
// When first bouncing off the paddle increase the speed to normal
if (!ball->firstBounce) {
ball->firstBounce = true;
ball->velocityMultiplier = 1.0f;
}
} else if (ball->shape.y + BALL_RADIUS > VIRTUAL_HEIGHT - PADDLE_HEIGHT + (BALL_RADIUS / 2.0f)) {
// Death or Game Over
if (player->lives > 0) {
player->lives -= 1;
ball->velocityMultiplier = 1.0f;
// Resetting ball's position
ball->shape.x = VIRTUAL_WIDTH / 2.0f;
ball->shape.y = VIRTUAL_HEIGHT / 2.0f;
} else {
}
ball->velocityApplied = false;
}
if (!ball->firstBounce) {
ball->velocityMultiplier = 0.5f;
}
ball->shape.x += ball->velocity.x * ball->velocityMultiplier;
ball->shape.y += ball->velocity.y * ball->velocityMultiplier;
}
int main() { int main() {
InitWindow(0, 0, "Breakout"); InitWindow(0, 0, "Breakout");
ToggleFullscreen(); ToggleFullscreen();
const int currentMonitor = GetCurrentMonitor(); const int CURRENT_MONITOR = GetCurrentMonitor();
const int monitorWidth = GetMonitorWidth(currentMonitor); const int MONITOR_WIDTH = GetMonitorWidth(CURRENT_MONITOR);
const int monitorHeight = GetMonitorHeight(currentMonitor); const int MONITOR_HEIGHT = GetMonitorHeight(CURRENT_MONITOR);
SetTargetFPS(60); SetTargetFPS(60);
@ -25,26 +94,38 @@ int main() {
// camera.offset = (Vector2){SCREEN_WIDTH / 2.0f, SCREEN_HEIGHT / 2.0f}; // camera.offset = (Vector2){SCREEN_WIDTH / 2.0f, SCREEN_HEIGHT / 2.0f};
camera.zoom = 1.0f; camera.zoom = 1.0f;
const RenderTexture2D renderTexture = LoadRenderTexture(VIRTUAL_WIDTH, VIRTUAL_HEIGHT); const RenderTexture2D RENDER_TEXTURE = LoadRenderTexture(VIRTUAL_WIDTH, VIRTUAL_HEIGHT);
const Rectangle renderTextureSrc = (Rectangle){0.0f, 0.0f, VIRTUAL_WIDTH, -VIRTUAL_HEIGHT}; const Rectangle RENDER_TEXTURE_SRC = (Rectangle){0.0f, 0.0f, VIRTUAL_WIDTH, -VIRTUAL_HEIGHT};
const Rectangle renderTextureDest = (Rectangle){0.0f, 0.0f, monitorWidth, monitorHeight}; const Rectangle RENDER_TEXTURE_DST = (Rectangle){0.0f, 0.0f, MONITOR_WIDTH, MONITOR_HEIGHT};
const Vector2 renderTextureOrig = {0}; const Vector2 RENDER_TEXTURE_POS = {0};
float paddleX = 0; Ball ball = {
Vector2 ballPos = (Vector2){VIRTUAL_WIDTH / 2.0f, VIRTUAL_HEIGHT / 2.0f}; (Rectangle){VIRTUAL_WIDTH / 2.0f, VIRTUAL_HEIGHT / 2.0f, BALL_RADIUS, BALL_RADIUS},
int score = 0; (Vector2){BALL_BASE_SPEED, BALL_BASE_SPEED},
1.0f,
false,
false,
};
Player player = {
(Rectangle){VIRTUAL_WIDTH / 2.0f, VIRTUAL_HEIGHT - PADDLE_HEIGHT - 10, PADDLE_WIDTH, PADDLE_HEIGHT}, 3, 0};
while (!WindowShouldClose()) { while (!WindowShouldClose()) {
Vector2 mouseDelta = GetMouseDelta(); // Keep before the cursor is disabled otherwise the paddle is stuck
MovePaddle(&player);
DisableCursor(); DisableCursor();
paddleX = Clamp(paddleX + mouseDelta.x, 0, VIRTUAL_WIDTH - PADDLE_WIDTH); MoveBall(&ball, &player);
// TraceLog(LOG_INFO, "%.0fx%.0f", ball.shape.x, ball.shape.y);
BeginTextureMode(renderTexture); BeginTextureMode(RENDER_TEXTURE);
{ {
ClearBackground(BLACK); ClearBackground(BLACK);
DrawRectangle(paddleX, VIRTUAL_HEIGHT - PADDLE_HEIGHT - 10, PADDLE_WIDTH, PADDLE_HEIGHT, RAYWHITE);
DrawRectangleRec(ball.shape, RAYWHITE);
DrawRectangleRec(player.shape, RAYWHITE);
} }
EndTextureMode(); EndTextureMode();
@ -53,19 +134,21 @@ int main() {
ClearBackground(BLACK); ClearBackground(BLACK);
BeginMode2D(camera); BeginMode2D(camera);
{ {
DrawCircle(ballPos.x, ballPos.y, 20, RAYWHITE); DrawTexturePro(RENDER_TEXTURE.texture, RENDER_TEXTURE_SRC, RENDER_TEXTURE_DST, RENDER_TEXTURE_POS, 0,
RAYWHITE);
DrawTexturePro(renderTexture.texture, renderTextureSrc, renderTextureDest, renderTextureOrig, 0, WHITE);
} }
EndMode2D(); EndMode2D();
// char score[] = "Score"; const char *scoreText = TextFormat("Score %08i", player.score);
const char *scoreText = TextFormat("Score %08i", score); // float scoreWidth = MeasureText(scoreText, FONT_SIZE) + 10;
float scoreWidth = MeasureText(scoreText, FONT_SIZE) + 10;
DrawText(scoreText, 10, 10, FONT_SIZE, RAYWHITE); DrawText(scoreText, 10, 10, FONT_SIZE, RAYWHITE);
const char *livesText = TextFormat("Lives %02i", player.lives);
DrawText(livesText, 10, 50, FONT_SIZE, RAYWHITE);
DrawFPS(GetScreenWidth() - 80, 5); DrawFPS(GetScreenWidth() - 80, 5);
// DrawText(TextFormat("%ix%i", monitorWidth, monitorHeight), 10, 40, FONT_SIZE, GOLD); // DrawText(TextFormat("%ix%i", monitorWidth, monitorHeight), 10, 40, FONT_SIZE, GOLD);
DrawText(TextFormat("Speed %.02f", ball.velocityMultiplier), 10, 90, FONT_SIZE, GOLD);
} }
EndDrawing(); EndDrawing();
} }