# Brick Breaker Game - Problem with brick and ball interactions

**URL:** https://discourse.processing.org/t/brick-breaker-game-problem-with-brick-and-ball-interactions/16763
**Category:** Coding Questions
**Created:** [December 31, 2019, 6:33pm UTC](https://discourse.processing.org/t/brick-breaker-game-problem-with-brick-and-ball-interactions/16763 "2019-12-31T18:33:45Z")
**Posts on this page:** 5
**Page:** 1

<div class="post-metadata">

### Author: ![shadowfire\_elite](https://yyz2.discourse-cdn.com/flex036/user_avatar/discourse.processing.org/shadowfire_elite/32/7680_2.png) [@shadowfire\_elite](https://discourse.processing.org/u/shadowfire_elite)
#### Post date: [December 31, 2019, 6:33pm UTC](https://discourse.processing.org/t/brick-breaker-game-problem-with-brick-and-ball-interactions/16763/1 "2019-12-31T18:33:45Z")

</div>

I’ve been trying for a long time to make a successful brick breaker game, but I’m still stuck on how to make the ball and bricks to interact. Can someone help me figure out a way for one brick to disappear when the ball touches it? I am mainly having trouble with the “bounceBrick” function in the brickBreaker class. I also think it has to do with the brick class, but I am not sure. Here’s the code:

```auto
int rows = 6; //Number of bricks per row
int columns = 6; //Number of columns
int total = rows * columns; //Total number of bricks

brickBreaker brickBreaker;
ball ball;
paddle paddle;
brick[] bricks = new brick[total]; 

void setup() {
  size(800, 650);
  brickBreaker = new brickBreaker();
  ball = new ball();
  paddle = new paddle();
  for (int i = 0; i < rows; i++)
  {
    for (int j = 0; j < columns; j++)
    {
      bricks[i*rows + j] = new brick((i+1) *width/(rows + 1), (j+1) * 75); //places all the bricks into the array, properly labelled.
    }
  }
}

void draw() {
  background(51);
  for (int i = 0; i < total; i++) {
    bricks[i].show();
}
    ball.show();
    paddle.update();
    brickBreaker.bounce();
    brickBreaker.reset();
    brickBreaker.showText();
    brickBreaker.bounceBrick();
}

void mousePressed() {
  brickBreaker.gameStart();
}

```

BrickBreaker Class

```auto
class brickBreaker {
  boolean gameStart;
  int score;
  int gameScore;
  boolean hit;
  int lives;
  boolean override;
  int rows = 6; //Number of bricks per row
  int columns = 6; //Number of columns
  int total = rows * columns; //Total number of bricks

  brickBreaker() {
    gameStart = false;
    score = 0;
    gameScore = 0;
    hit = false;
    lives = 5;
    override = false;
  }

  void gameStart() {
    if (gameStart == false) {
      gameStart = !gameStart;
    }
  }

  void bounce() {
    if (gameStart) {

      ball.update();

      // If ball hits paddle, switch direction
      if (ball.x > mouseX - paddle.psize/2 && ball.x < mouseX + paddle.psize/2 && ball.y == paddle.y) {

        // Bounce
        ball.vy = ball.vy * -1;

        // Decrease paddle size
        paddle.psize -= 5;
      }
  }
}

  void reset() {
    if (ball.y > height) {
      ball.x = 400;
      ball.y = 560;
      ball.vx = 4;
      ball.vy = 4;
      lives -= 1;
      gameStart = false;
    }
    if (lives <= 0) {
      gameOver();
    }
    if (score == total) {
      win();
    }
  }

  void resetGame() {
    ball.x = 400;
    ball.y = 560;
    gameStart = false;
    paddle.psize = 150;
    paddle.y = 600;
    ball.vx = 4;
    ball.vy = 4;
    score = 0;
    gameScore = 0;
    lives = 5;
    //Setup array of all bricks on screen
    for (int i = 0; i < rows; i++)
    {
      for (int j = 0; j< columns; j++)
      {
        bricks[i*rows + j] = new brick((i+1) *width/(rows + 1), (j+1) * 80);
      }
    }
  }

  // Where Score and Lives is located
  void showText() {
    if (override == false) {
      textSize(50);     
      fill(255);          
      stroke(0);
      text(gameScore, 20, 50);
      textSize(25);
      text("Lives:", 20, 575);
      text(lives, 90, 575);
    }
  }

  void hit() {
    if (hit == true) {
    }
  }

  void gameOver() {
    override = true;
    if (override == true) {
      ball.x = -100;
      ball.vx = 0;
      ball.vy = 0;
      paddle.y = -100;
      textSize(50);
      fill(255, 0, 0);
      text("GAME OVER!!!", 250, 200);
      text("Score: ", 300, 300);
      text(gameScore, 450, 300);
      text("Click mouse to play again!", 100, 400);
      if (mousePressed) {
        override = false;
        resetGame();
      }
    }
  }

  void win() {
    override = true;
    if (override == true) {
      ball.x = -10;
      ball.vx = 0;
      ball.vy = 0;
      paddle.y = -50;
      textSize(50);
      fill(random(255), random(255), random(255));
      text("YOU WON!!!", 250, 200);
      text("Score: ", 300, 300);
      text(gameScore, 450, 300);
      text("Click mouse to play again!", 100, 400);
      if (mousePressed) {
        override = false;
        resetGame();
      }
    }
  }

  void bounceBrick() {
    for (int i = 0; i < total; i ++)
    {
      //If ball hits bottom of brick, ball moves down, increment score
      if (ball.y <= bricks[i].y + bricks[i].h/2 && ball.y > bricks[i].y && ball.x >= bricks[i].x - bricks[i].w/2 && ball.x <= bricks[i].x + bricks[i].w/2)
      {
        ball.vy *= -1;
        gameScore += 5;
        bricks[i].hit();
        hit = true;
      } 

      //If ball hits top of brick ball moves up, increment score
      if (ball.y >= bricks[i].y && ball.y <= bricks[i].y + bricks[i].h/2 && ball.x >= bricks[i].x && ball.x <= bricks[i].x + bricks[i].w) 
      {
        ball.vy *= -1;
        gameScore += 5;       
        bricks[i].hit();
        hit = true;
      }

      //if ball hits the left of the brick, ball switches to the right, and moves in same direction, increment score
      if (ball.x >= bricks[i].x && ball.x <= bricks[i].x + bricks[i].w/2 && ball.y >= bricks[i].y && ball.y <= bricks[i].y + bricks[i].h)
      {
        ball.vx *= -1;
        gameScore += 5;
        bricks[i].hit();
        hit = true;
      }

      //if ball hits the right of the brick, ball switches to the left, and moves in same direction, increment score
      if (ball.x <= bricks[i].x + bricks[i].w && ball.x >= bricks[i].x + bricks[i].w/2 && ball.y >= bricks[i].y && ball.y <= bricks[i].y + bricks[i].h)
      {
        ball.vx *= -1;
        gameScore += 5;
        bricks[i].hit();
        hit = true;
      }
    }
  }
}

```

Ball Class

```auto
class ball {

  float dia;
  float x;
  float y;
  float vx;
  float vy;
  color col;

  ball() {
    dia = 24;
    x = 400;
    y = 560;
    vx = 4;
    vy = 4;
    col = color(random(128, 255));
  }

  void show() {
    fill(col);
    ellipseMode(CENTER);
    ellipse(x, y, dia, dia);
  }

  void update () {
    x = x + vx;
    y = y + vy;

    if (x > width || x < 0) {
      vx = vx * -1;
    } else if (y > height || y < 0) {
      vy = vy * -1;
    }
  }
}

```

Paddle Class

```auto
class paddle {

  int psize;
  color pcol;
  float y;

  paddle () {
    psize = 150;
    pcol = color(random(128, 255));
    y = 600;
  }

  void update() {
    fill(pcol);
    rectMode(CENTER);
    rect(mouseX, y, psize, 10, 30);
  }
}

```

Brick Class

```auto
class brick {

  color bcol;
  float x;
  float y;
  float h; 
  float w;

  brick(float tempX, float tempY) {
    bcol = color(random(128, 255), random(128, 255), random(128, 255));
    x = tempX;
    y = tempY;
    w = 60;
    h = 37.5;
  }

  void show() {
    noStroke();
    fill(bcol);
    rect(x, y, w, h);
  }

  void hit() {
    if (brickBreaker.hit == true) {
      for (int i = 0; i < total; i++) {
        bcol = color(51);
        rect(x, y, w, h);
        brickBreaker.hit = false;
      }
    }
  }
}

```

---

<div class="post-metadata">

### Author: ![Lexyth](https://yyz2.discourse-cdn.com/flex036/user_avatar/discourse.processing.org/lexyth/32/7403_2.png) [@Lexyth](https://discourse.processing.org/u/Lexyth)
#### Post date: [December 31, 2019, 7:51pm UTC](https://discourse.processing.org/t/brick-breaker-game-problem-with-brick-and-ball-interactions/16763/2 "2019-12-31T19:51:15Z")

</div>

You don‘t need to call to another class. Just add a **broken** boolean to the brick class. If that boolean is false, draw the brick, else don‘t.

To set that boolean to true, just use the hit method you already have.

And then just check if the brick is !broken when drawing the rect for it.

---

<div class="post-metadata">

### Author: ![shadowfire\_elite](https://yyz2.discourse-cdn.com/flex036/user_avatar/discourse.processing.org/shadowfire_elite/32/7680_2.png) [@shadowfire\_elite](https://discourse.processing.org/u/shadowfire_elite)
#### Post date: [December 31, 2019, 11:18pm UTC](https://discourse.processing.org/t/brick-breaker-game-problem-with-brick-and-ball-interactions/16763/3 "2019-12-31T23:18:49Z")

</div>

By “broken” boolean, do you mean a boolean set to false or a boolean with the name being “broken”? And if I understand correct, with this method, I have to draw each brick separately. That will be a lot of code…

Are there any tips you can give me that can help with taking out one brick at a time with an array?

---

<div class="post-metadata">

### Author: ![kll](https://yyz2.discourse-cdn.com/flex036/user_avatar/discourse.processing.org/kll/32/964_2.png) [@kll](https://discourse.processing.org/u/kll)
#### Post date: [January 1, 2020, 8:20am UTC](https://discourse.processing.org/t/brick-breaker-game-problem-with-brick-and-ball-interactions/16763/4 "2020-01-01T08:20:26Z")

</div>

if you not understand the idea to give each Brick a variable about  
enable / disable draw …

you tell us HOW you want to remember if a `Brick` in the `bricks` array  
is dead after collision with a ball?

* * *

please use for class big letters,  
class Brick  
class Ball

Ball ball;  
Brick[] bricks;  
…  
and all other variables start small…

---

<div class="post-metadata">

### Author: ![Lexyth](https://yyz2.discourse-cdn.com/flex036/user_avatar/discourse.processing.org/lexyth/32/7403_2.png) [@Lexyth](https://discourse.processing.org/u/Lexyth)
#### Post date: [January 1, 2020, 8:02pm UTC](https://discourse.processing.org/t/brick-breaker-game-problem-with-brick-and-ball-interactions/16763/5 "2020-01-01T20:02:00Z")

</div>

Yes, broken should be the variable name, signifying if the brick is still intact(false), or broken (true).

You have 2 options. Either draw each brick seperately in a for loop, or draw a rect that represents all bricks and overlay them with a new rect when they are broken.

I‘d highly suggest drawing each brick seperately, Else you just end up withdrawing each overlay seperately, but adding a Ton of Code that could‘ve been avoided.

Take a look here, to see how it could be done :

> **Example**
>
> ```auto
> Ball ball;
> Brick[] bricks;
> 
> void setup() {
> size(screen.width, screen.height);
>    
> ball = new Ball(150, 10, 10);
>    
> bricks = new Brick[100];
>    
> for (int x = 0; x < 10; x++) {
> for (int y = 0; y < 10; y++) {
> println("1");
> bricks[x+y*10] = new Brick(50+x*20, 50+y*10, 20, 10);
> }
> }
> }
> 
> void draw() {
> background(0,0,255);
>    
> for (int i = 0; i < bricks.length; i++) {
> bricks[i].display();
> bricks[i].hit(ball);
> }
>    
> ball.display();
> ball.move();
> ball.checkCollission();
> }
> 
> ```
> 
> ```auto
> class Brick {
> PVector pos; //basically 2 floats (or 3 if you need another one)
> PVector siz;
>    
> bool broken = false; // change bool to boolean (i use diff compiler, so for me it's bool)
>    
> Brick(float x, float y, float w, float h) {
> pos = new PVector(x, y);
> siz = new PVector(w, h);
> }
>    
> void display() {
> if (!broken) {
> rect(pos.x, pos.y, siz.x, siz.y);
> }
> }
>    
> void hit(Ball b) {
>       
> if (!broken && b.pos.x + b.radius/2 > pos.x && b.pos.x - b.radius/2 < pos.x + siz.x && b.pos.y + b.radius/2 > pos.y && b.pos.y - b.radius/2 < pos.y + siz.y) {
> //could add something like a counter for the bricks that need multiple hits
> broken = true;
>          
> //you'll have to adapt the reflection direction calculation...
> if (b.pos.x < pos.x || b.pos.x > pos.x + siz.x)
> b.reflect(-1,1);
> else if (b.pos.y < pos.y || b.pos.y > pos.y + siz.y) b.reflect(1,-1);
> }
> }
> }
> 
> ```
> 
> ```auto
> class Ball {
> PVector pos;
> PVector dir;
> float radius;
>    
> Ball(float x, float y, float r) {
> pos = new PVector(x, y);
> dir = new PVector(random(-1,1), random(1));
> radius = r;
> }
>    
> void display() {
> ellipse(pos.x, pos.y, radius, radius);
> }
>    
> void move() {
> pos.add(dir);
> }
>    
> void checkCollission() {
> if (pos.x - radius/2 < 0 || pos.x + radius/2 > 300)dir.x *= -1;
> if (pos.y - radius/2 < 0 || pos.y + radius/2 > 200)dir.y *= -1;
>       
> }
>    
> void reflect(float x, float y) {
> dir.x *= x;
> dir.y *= y;
> }
> }
> 
> ```
> 
> It‘s not the best brickbreaker, but it works (though the reflection isn‘t perfect…).
