Blocks that break and give score

master
Wynd 2025-08-30 01:22:02 +03:00
parent 7b20ce4436
commit 47f1144fa7
1 changed files with 75 additions and 13 deletions

88
main.c
View File

@ -7,14 +7,17 @@
#define FONT_SIZE 30 #define FONT_SIZE 30
#define PLAYER_LIVES 2
#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_RADIUS (VIRTUAL_WIDTH / 80.0)
#define BALL_BASE_SPEED 2.0f #define BALL_BASE_SPEED 2.0f
#define BALL_MUL_SPEED 0.15f #define BALL_MUL_SPEED 0.15f
#define LEN(arr) (sizeof arr / sizeof *arr)
typedef struct Player { typedef struct Player {
Rectangle shape; Rectangle shape;
int lives; int lives;
@ -29,22 +32,41 @@ typedef struct Ball {
bool velocityApplied; bool velocityApplied;
} Ball; } Ball;
typedef struct Block {
Rectangle shape;
Color color;
bool isDestroyed;
} Block;
void MovePaddle(Player *player) { void MovePaddle(Player *player) {
Vector2 mouseDelta = GetMouseDelta(); Vector2 mouseDelta = GetMouseDelta();
player->shape.x = Clamp(player->shape.x + mouseDelta.x, 0, VIRTUAL_WIDTH - PADDLE_WIDTH); player->shape.x = Clamp(player->shape.x + mouseDelta.x, 0, VIRTUAL_WIDTH - PADDLE_WIDTH);
} }
void ResetBall(Ball *ball) {
ball->velocityMultiplier = 1.0f;
// Resetting ball's position
ball->velocity = (Vector2){BALL_BASE_SPEED, BALL_BASE_SPEED};
ball->firstBounce = false;
ball->shape.x = VIRTUAL_WIDTH / 2.0f;
ball->shape.y = VIRTUAL_HEIGHT / 2.0f;
}
void MoveBall(Ball *ball, Player *player) { void MoveBall(Ball *ball, Player *player) {
bool isColliding = CheckCollisionRecs(player->shape, ball->shape); bool isColliding = CheckCollisionRecs(player->shape, ball->shape);
if (ball->shape.x - BALL_RADIUS < 0 || ball->shape.x + BALL_RADIUS > VIRTUAL_WIDTH) { if (ball->shape.x < 0 || ball->shape.x + BALL_RADIUS > VIRTUAL_WIDTH) {
ball->velocity = Vector2Multiply(ball->velocity, (Vector2){-1.0f, 1.0f}); ball->velocity = Vector2Multiply(ball->velocity, (Vector2){-1.0f, 1.0f});
ball->velocityApplied = false; ball->velocityApplied = false;
} else if (ball->shape.y - BALL_RADIUS < 0) { } else if (ball->shape.y < 0) {
ball->velocity = Vector2Multiply(ball->velocity, (Vector2){1.0f, -1.0f}); ball->velocity = Vector2Multiply(ball->velocity, (Vector2){1.0f, -1.0f});
ball->velocityApplied = false; ball->velocityApplied = false;
} else if (isColliding) { } else if (isColliding) {
ball->velocity = Vector2Multiply(ball->velocity, (Vector2){1.0f, -1.0f}); float direction = 1 - (ball->shape.x + (BALL_RADIUS / 2.0f)) / (player->shape.x + (PADDLE_WIDTH / 2.0f) + 1);
float forceX = 1.0f; // direction > 0 ? 1.0f : -1.0f;
float forceY = -1.0f; // + (direction * 10.0);
TraceLog(LOG_INFO, "%f %f %f", direction, forceX, forceY);
ball->velocity = Vector2Multiply(ball->velocity, (Vector2){forceX, forceY});
// Add speed multiplier every bounce to increase difficulty // Add speed multiplier every bounce to increase difficulty
if (!ball->velocityApplied) { if (!ball->velocityApplied) {
@ -63,10 +85,7 @@ void MoveBall(Ball *ball, Player *player) {
// Death or Game Over // Death or Game Over
if (player->lives > 0) { if (player->lives > 0) {
player->lives -= 1; player->lives -= 1;
ball->velocityMultiplier = 1.0f; ResetBall(ball);
// Resetting ball's position
ball->shape.x = VIRTUAL_WIDTH / 2.0f;
ball->shape.y = VIRTUAL_HEIGHT / 2.0f;
} else { } else {
} }
ball->velocityApplied = false; ball->velocityApplied = false;
@ -91,7 +110,6 @@ int main() {
SetTargetFPS(60); SetTargetFPS(60);
Camera2D camera = {0}; // Game world camera Camera2D camera = {0}; // Game world camera
// camera.offset = (Vector2){SCREEN_WIDTH / 2.0f, SCREEN_HEIGHT / 2.0f};
camera.zoom = 1.0f; camera.zoom = 1.0f;
const RenderTexture2D RENDER_TEXTURE = LoadRenderTexture(VIRTUAL_WIDTH, VIRTUAL_HEIGHT); const RenderTexture2D RENDER_TEXTURE = LoadRenderTexture(VIRTUAL_WIDTH, VIRTUAL_HEIGHT);
@ -108,24 +126,68 @@ int main() {
}; };
Player player = { Player player = {
(Rectangle){VIRTUAL_WIDTH / 2.0f, VIRTUAL_HEIGHT - PADDLE_HEIGHT - 10, PADDLE_WIDTH, PADDLE_HEIGHT}, 3, 0}; (Rectangle){VIRTUAL_WIDTH / 2.0f, VIRTUAL_HEIGHT - PADDLE_HEIGHT - 10, PADDLE_WIDTH, PADDLE_HEIGHT},
PLAYER_LIVES, 0};
const int BLOCK_ROWS = 7;
const int BLOCKS_PER_ROW = 15;
const int BLOCK_WIDTH = VIRTUAL_WIDTH / (float)BLOCKS_PER_ROW;
const int BLOCK_HEIGHT = 20;
Block blocks[BLOCK_ROWS * BLOCKS_PER_ROW];
for (int i = 0; i < BLOCK_ROWS; i++) {
for (int j = 0; j < BLOCKS_PER_ROW; j++) {
int id = i + (j * BLOCK_ROWS);
int blockX = j * (BLOCK_WIDTH + 1);
int blockY = 10 + i * (BLOCK_HEIGHT + 1);
int hue = (id % BLOCK_ROWS) * 400;
Color color = ColorFromHSV(hue, 1.0f, 1.0f);
blocks[id] = (Block){(Rectangle){blockX, blockY, BLOCK_WIDTH, BLOCK_HEIGHT}, color, false};
}
}
const int BLOCK_COUNT = LEN(blocks);
while (!WindowShouldClose()) { while (!WindowShouldClose()) {
if (IsKeyDown(KEY_R)) {
ResetBall(&ball);
}
// Keep before the cursor is disabled otherwise the paddle is stuck // Keep before the cursor is disabled otherwise the paddle is stuck
MovePaddle(&player); MovePaddle(&player);
DisableCursor(); DisableCursor();
MoveBall(&ball, &player); MoveBall(&ball, &player);
// TraceLog(LOG_INFO, "%.0fx%.0f", ball.shape.x, ball.shape.y);
BeginTextureMode(RENDER_TEXTURE); BeginTextureMode(RENDER_TEXTURE);
{ {
ClearBackground(BLACK); ClearBackground(BLACK);
DrawRectangleRec(ball.shape, RAYWHITE); DrawRectangleRec(ball.shape, RAYWHITE);
// DrawRectangle(ball.shape.x + BALL_RADIUS / 2.0f, ball.shape.y + BALL_RADIUS / 2.0f, 5, 5, RED);
DrawRectangleRec(player.shape, RAYWHITE); DrawRectangleRec(player.shape, RAYWHITE);
// DrawRectangle(player.shape.x + PADDLE_WIDTH / 2.0f, player.shape.y, 5, 5, RED);
for (int i = 0; i < BLOCK_COUNT; i++) {
Block *block = &blocks[i];
if (block->isDestroyed) {
continue;
}
bool isColliding = CheckCollisionRecs(ball.shape, block->shape);
if (isColliding) {
ball.velocity = Vector2Multiply(ball.velocity, (Vector2){1.0f, -1.0f});
block->color = BLACK;
block->isDestroyed = true;
player.score += 100;
}
DrawRectangleRec(block->shape, block->color);
}
} }
EndTextureMode(); EndTextureMode();