From 4f433796b497df98d195a97042f42e02b6f3a450 Mon Sep 17 00:00:00 2001 From: Gregory Eremin Date: Sun, 4 Oct 2015 16:53:19 +0300 Subject: [PATCH] Implement ball and basic collisions --- src/breakout.hpp | 3 ++ src/brick.cpp | 19 +++++++++++++ src/brick.hpp | 3 ++ src/scene.cpp | 74 ++++++++++++++++++++++++++++++++++++++++++++++-- src/scene.hpp | 7 +++++ 5 files changed, 104 insertions(+), 2 deletions(-) diff --git a/src/breakout.hpp b/src/breakout.hpp index 32667d1..f845c9a 100644 --- a/src/breakout.hpp +++ b/src/breakout.hpp @@ -5,12 +5,15 @@ #define SCREEN_WIDTH 407 #define SCREEN_HEIGHT 600 +#define BALL_RADIUS 8 + #define PAD_WIDTH 100 #define PAD_HEIGHT 10 #define KEY_MOVE_STEP 5 #define BRICK_ROWS 7 #define BRICK_COLS 8 +#define NUM_BRICKS BRICK_ROWS*BRICK_COLS #define BRICK_WIDTH 50 #define BRICK_HEIGHT 15 diff --git a/src/brick.cpp b/src/brick.cpp index c461ac0..8814dcb 100644 --- a/src/brick.cpp +++ b/src/brick.cpp @@ -7,11 +7,30 @@ Brick::Brick(SDL_Renderer *r, int x, int y, Color c) { brick.w = BRICK_WIDTH; brick.h = BRICK_HEIGHT; color = c; + visible = true; } Brick::~Brick() {} +bool Brick::collides_with(int x1, int y1, int x2, int y2) { + return ( + visible && + brick.x < x2 && + brick.x + BRICK_WIDTH > x1 && + brick.y < y2 && + brick.y + BRICK_HEIGHT > y1 + ); +} + +void Brick::destroy() { + visible = false; +} + void Brick::render() { + if (!visible) { + return; + } + switch (color) { case RED: SDL_SetRenderDrawColor(renderer, 255, 51, 51, 255); diff --git a/src/brick.hpp b/src/brick.hpp index b3bd389..2cacff8 100644 --- a/src/brick.hpp +++ b/src/brick.hpp @@ -16,10 +16,13 @@ public: Brick(SDL_Renderer *r, int x, int y, Color c); ~Brick(); + bool collides_with(int x1, int y1, int x2, int y2); + void destroy(); void render(); private: SDL_Renderer *renderer; SDL_Rect brick; Color color; + bool visible; }; diff --git a/src/scene.cpp b/src/scene.cpp index e7c5579..e9f8cc3 100644 --- a/src/scene.cpp +++ b/src/scene.cpp @@ -5,10 +5,19 @@ Scene::Scene(SDL_Renderer *r) { renderer = r; pad.x = (SCREEN_WIDTH - PAD_WIDTH) / 2; - pad.y = (SCREEN_HEIGHT - PAD_HEIGHT); + pad.y = SCREEN_HEIGHT - PAD_HEIGHT; pad.w = PAD_WIDTH; pad.h = PAD_HEIGHT; + ball.x = SCREEN_WIDTH/2 - BALL_RADIUS; + ball.y = SCREEN_HEIGHT/2 - BALL_RADIUS; + ball.w = BALL_RADIUS * 2; + ball.h = BALL_RADIUS * 2; + ball_moving = true; + ball_velx = 0; + ball_vely = 0; + launch_ball(); + for (int i = 0; i < BRICK_ROWS; i++) { for (int j = 0; j < BRICK_COLS; j++) { bricks.push_back(Brick(renderer, j * BRICK_WIDTH + j, i * BRICK_HEIGHT + i, (Color)i)); @@ -21,13 +30,24 @@ Scene::Scene(SDL_Renderer *r) { Scene::~Scene() {} void Scene::render() { + // Draw background SDL_SetRenderDrawColor(renderer, 0, 0, 0, 255); SDL_RenderClear(renderer); + + // Draw pad SDL_SetRenderDrawColor(renderer, 255, 255, 255, 255); SDL_RenderFillRect(renderer, &pad); - for (int i = 0; i < BRICK_ROWS * BRICK_COLS; i++) { + + // Draw bricks + for (int i = 0; i < NUM_BRICKS; i++) { bricks[i].render(); } + + // Draw ball + move_ball(); + SDL_SetRenderDrawColor(renderer, 255, 255, 255, 255); + SDL_RenderFillRect(renderer, &ball); + SDL_RenderPresent(renderer); } @@ -44,3 +64,53 @@ void Scene::move_pad(int x) { void Scene::move_pad_relative(int delta) { move_pad(pad.x + delta); } + +void Scene::launch_ball() { + ball_moving = true; + ball_velx = 3; + ball_vely = -2; +} + +void Scene::move_ball() { + if (!ball_moving) { + return; + } + + ball.x += ball_velx; + ball.y += ball_vely; + + // Collisions + + // Left + if (ball.x <= 0) { + ball_velx = -ball_velx; + } + // Right + if (ball.x >= SCREEN_WIDTH - 2*BALL_RADIUS) { + ball_velx = -ball_velx; + } + // Top + if (ball.y <= 0) { + ball_vely = -ball_vely; + } + // Bottom + if (ball.y >= SCREEN_HEIGHT) { + // Game over + } + // Pad + if (ball.x >= pad.x && ball.x <= pad.x + PAD_WIDTH && ball.y + 2*BALL_RADIUS >= pad.y) { + ball_vely = -ball_vely; + } + // Bricks + for (int i = NUM_BRICKS; i > 0; --i) { + int x1 = ball.x; + int y1 = ball.y; + int x2 = ball.x + 2*BALL_RADIUS; + int y2 = ball.y + 2*BALL_RADIUS; + + if (bricks[i].collides_with(x1, y1, x2, y2)) { + ball_vely = -ball_vely; + bricks[i].destroy(); + } + } +} diff --git a/src/scene.hpp b/src/scene.hpp index ead0e33..428c6bc 100644 --- a/src/scene.hpp +++ b/src/scene.hpp @@ -11,9 +11,16 @@ public: void render(); void move_pad(int x); void move_pad_relative(int delta); + void launch_ball(); private: + void move_ball(); + SDL_Renderer *renderer; + bool ball_moving; + int ball_velx; + int ball_vely; + SDL_Rect ball; SDL_Rect pad; std::vector bricks; };