1
0
Fork 0

Implement ball and basic collisions

This commit is contained in:
Gregory Eremin 2015-10-04 16:53:19 +03:00
parent e6c1e2a15a
commit 4f433796b4
5 changed files with 104 additions and 2 deletions

View File

@ -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

View File

@ -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);

View File

@ -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;
};

View File

@ -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();
}
}
}

View File

@ -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<Brick> bricks;
};