BREAKOUT Project - Help with collision detection

Hello everyone! I’m new to Processing and attempting to create a version of Breakout. I am nearing the end of my project but I didn’t find any good way/solution to make my bricks disappear when the ball hits them. I feel like I maybe did something wrong and that might be the reason why I don’t find any way to make it work properly.

I tried to make it work with a boolean (checkCollisionWithRec) but it didn’t work at all.

Based on my code, do tou see any solution I could use to make it work? Your answers and help would be very appreciated! Thank you!

Here is what it looks like :

//Variables de ma balle
int xBalle = 650; 
int yBalle = 400; 
int xSpeed = 3; 
int ySpeed = 3; 

//Variables des briques
float by;
float bx;
float bh = 30; //Hauteur
float bw = 100; //Largeur

//Variables du paddle
int xPaddle = 600; 
int yPaddle = 650; 
int Paddle = 100; 
void setup(){
  size(1200,800); 
 }

void draw(){
  background(0); 
  
  //Je fais bouger ma balle
  xBalle = xBalle + xSpeed; //
  if (xBalle > width || xBalle < 0){ //Ma balle ne sort pas de l'écran par les côtés
    xSpeed = xSpeed * -1; //Inverse vitesse
  }  
  yBalle = yBalle + ySpeed; //
  if (yBalle > height || yBalle < 0){ //Ma balle ne sort pas de l'écran par le haut et le bas
    ySpeed = ySpeed * -1; //Inverse vitesse
  }
  
  //Je dessine ma balle
  fill(255); 
  stroke(255); 
  ellipse (xBalle,yBalle,20,20); 
  
  //Je fais bouger mon paddle - keyPressed
  if (keyPressed){
    if(keyCode == RIGHT){ 
    //Déplacement du paddle à droite en x
    xPaddle = xPaddle + 10; 
    } else if (keyCode == LEFT){ 
    //Déplacement du paddle à gauche
    xPaddle = xPaddle - 10; 
    }
  }
  
  //Le paddle ne sort pas de l'écran par les côtés 
   if (xPaddle > width) 
   xPaddle = width;
   if (xPaddle < 0) 
   xPaddle = 0;
  
  //Je dessine mon paddle 
  fill(255); 
  stroke(255); 
  rectMode(CENTER);
  rect(xPaddle,yPaddle,200,10); 
  
  //Ma balle rebondit sur le paddle   
    if ((xPaddle - Paddle) < xBalle && (xPaddle + Paddle) > xBalle && 
    (yPaddle - 10) < yBalle && (yPaddle) > yBalle) {
    // Si la balle rebondit sur le paddle, inverse la vitesse 
    ySpeed = - ySpeed;
  }
  
  //Je dessine mes briques
  //Première boucle (hauteur)
  for (float by = 1; by < 6; by++) { //6-1=5
  //Seconde boucle (largeur)
  for (float bx = 1; bx < 11; bx++) { //11-1=10
    fill(255); 
    stroke(255); 
    rect(bx * 110, by * 50, bw, bh);
  }
  }
  
  //Détection entre ma balle et les briques
   
}
1 Like

“Always use classes because they’re super helpful” - myself

If I were you, I would create a brick class for each brick, then check the collision the same way you did for the paddle (which is working, right?). If you detect a collision change the direction of the ball and stop drawing the brick, and stop detecting collision.

If you are having trouble detecting collision I would checkout this video: https://www.youtube.com/watch?v=IIrC5Qcb2G4

In this video, the CodingTrain creates pingpong, the collision he does is similair to what you would have to do in your breakout project.

3 Likes

but if a beginner not ready to learn classes
( and actually it would need to be ‘Array of class’ )
why not just start with a ARRAY as ArrayList
https://processing.org/reference/ArrayList.html
to store X and Y position of the bricks
can use class or just PVector
https://processing.org/reference/PVector.html

example:

int xBalle = 650, yBalle = 400, xSpeed = 3, ySpeed = 3; //________ Variables de ma balle
float by, bx, bh = 30, bw = 100; //_______________________________ Variables des briques
int xPaddle = 600, yPaddle = 650, lPaddle = 100; //_______________ Variables du paddle 

void setup() {
  size(1200, 800);
  make_bricks();
}

void draw() {
  background(0);
  ball();
  paddle();
  draw_bricks();
}

void ball() { //_______________________________________________ Je fais bouger ma balle
  xBalle = xBalle + xSpeed;
  yBalle = yBalle + ySpeed;
  if (xBalle > width  || xBalle < 0) xSpeed = xSpeed * -1; 
  if (yBalle > height || yBalle < 0) ySpeed = ySpeed * -1;
  fill(255); 
  stroke(255); 
  ellipse (xBalle, yBalle, 20, 20); //__________________________ Je dessine ma balle
}

void paddle() {
  if      (keyPressed && keyCode == RIGHT)  xPaddle += 10;  //__ Je fais bouger mon paddle - keyPressed
  else if (keyPressed && keyCode == LEFT)   xPaddle -= 10;

  if (xPaddle > width)  xPaddle = width;  //____________________ Le paddle ne sort pas de l'écran par les côtés 
  if (xPaddle < 0)      xPaddle = 0;

  fill(255); 
  stroke(255); 
  rectMode(CENTER);
  rect(xPaddle, yPaddle, 200, 10); //___________________________ Je dessine mon paddle 

  if ( (xPaddle - lPaddle) < xBalle && (xPaddle + lPaddle) > xBalle &&   //Ma balle rebondit sur le paddle   
    (yPaddle - 10) < yBalle && (yPaddle) > yBalle ) 
    ySpeed = - ySpeed; // Si la balle rebondit sur le paddle, inverse la vitesse
}

/*
void bricks() { //______________________________________________ Je dessine mes briques
 for (float by = 1; by < 6; by++) { // 1 .. 5
 for (float bx = 1; bx < 11; bx++) { // 1 .. 10
 fill(255); 
 stroke(255); 
 rect(bx * 110, by * 50, bw, bh);
 }
 }
 
 //Détection entre ma balle et les briques
 }
 */

ArrayList<PVector> bricks= new ArrayList<PVector>();

void make_bricks() {
  for (float by = 1; by < 6; by++) { // 1 .. 5
    for (float bx = 1; bx < 11; bx++) { // 1 .. 10
      bricks.add(new PVector(bx * 110, by * 50) );
    }
  } 
  //println(bricks);
}

void draw_bricks() {
  for ( PVector p : bricks ) rect(p.x, p.y, bw, bh);
}

sorry about different writing style, for me more easy to read…

3 Likes

Yep, you are definitely right, might not be worth learning classes right now. I personally think that classes are easier because I use them so much.

1 Like

why not just teach both?
OP can choose…

2 Likes

Hello guys! Thank you very much for you answers, it’s very appreciated!

Actually, I haven’t learned about class yet which is why I avoided using it. I will make some changes. Following you, would it be possible to use Array rather than ArrayList? If yes, can I combine an array and the for loop I used to draw my bricks?

I will also check the Coding Train, video.

Again, thank you very much!

1 Like

hmm… my reason to go for arraylist is that has a
https://py.processing.org/reference/list_remove.html

so after collision could use that to remove a brick from bricks

with a array not have that so easy…


did you try my code?

the

 for ( PVector p : bricks ) rect(p.x, p.y, bw, bh);

is a beauty? NOT ?

I actually did try your code, it is pure beauty. Actually, I have never used ArrayList before, I was just trying to find a way and work with tools that I know.

But it works great, thank you!

I had a look at “remove” for the ArrayList, how do you actually use it in the actual code in order to make the bricks disappear?

To remove it loop through each one and check if it is touching the ball, if it is, then you should remove it.

You can loop through the same way as above

for ( PVector p : bricks )

1 Like

If you need a tutorial on Array List’s you can check out this one:

That should be good.

And, remember, never be afraid to learn new things, it sure can be daunting at the beginning, but in the end it is well worth it.

5 Likes

yes, there are 2 ways to loop over arrayList

  for ( int i = 0 ; i < bricks.size(); i++ ) { 
    PVector p = bricks.get(i);
    rect(p.x, p.y, bw, bh);
collision
if ( p.x < xBalle && (p.x + bw) > xBalle &&   //__Ma balle rebondit sur les briques  
  p.y < yBalle && p.y +bh > yBalle && ySpeed < 0 ) { //_____ also check on UPSPEED ??
  ySpeed = - ySpeed; // Si la balle rebondit sur les briques, inverse la vitesse
  bricks.remove(i);
    }
  }
2 Likes

@BeastCoder
good video // but not too beginner friendly
also i miss the real advantages like .remove or see here?
https://processing.org/reference/StringList.html

1 Like

Ack, you are right!

I’ll try and find a more beginner friendly one, I tried to use a Coding Train one but he was doing something a little bit more complicated using classes.

1 Like

Putting everything together. Thank you very much for the help!

1 Like

Studio.ProcessingTogether.com/sp/pad/export/ro.PKnDDqu1vYo

3 Likes

Hello everyone, it’s me, again!

Since my last posts yesterday, I learned that I couldn’t use Class, Object and ArrayList so I had to redo everything.

I used an array for my “for loop” that draws my bricks. For the collision, I did the same way I did for the paddle as @BeastCoder suggested. It is functioning but I have got some problems with the collision detection.

Sometimes, the ball will hit a brick and it is the one next to it that will disappear and not the one that got hit.

Sometimes, the ball will hit a brick’ side and it won’t disappear at all.

Here is my code :

//Briques
int[] blocks = new int[50];
int bh = 30; //Hauteur 
int bw = 100; //Largeur

//Variables de ma balle
float xBalle = 650; //Position x
float yBalle = 400; //Position y
float xSpeed = 3; //Vitesse
float ySpeed = 3; //Vitesse

//Variables du paddle
int xPaddle = 600; //Position x
int yPaddle = 650; //Position y 
int Paddle = 100; 


void setup(){
  int i;
  size(1200, 800); //Taille de la fenêtre - les dimensions de la fenêtre ont été changées pour mieux s'adapter à celles de mon écran
  
  //Array pour les briques 
  for (i=0; i<50; i++) {
    blocks[i] = 1;
  }
}

void draw(){
  int i; //Boucle
  int bx; //Briques x
  int by; //Briques y
  background (0);

//Je fais bouger ma balle
  xBalle = xBalle + xSpeed; //Ajout de vitesse à ma xBalle
  if (xBalle > width || xBalle < 0){ //Ma balle ne sort pas de l'écran par les côtés
  xSpeed = xSpeed * -1; //Inverse vitesse
  }  
  yBalle = yBalle + ySpeed; //Ajout de vitesse à ma yBalle
  if (yBalle > height || yBalle < 0){ //Ma balle ne sort pas de l'écran par le haut et le bas
  ySpeed = ySpeed * -1; //Inverse vitesse
  }
  
  //Je dessine ma balle
  fill(255); 
  stroke(255); 
  ellipse (xBalle,yBalle,20,20); //Si diamètre 40, rayon 20
  
  //Je fais bouger mon paddle - keyPressed
  if (keyPressed){
    if(keyCode == RIGHT){ //bouton DROIT
    //Déplacement du paddle à droite
    xPaddle = xPaddle + 10; 
    } else if (keyCode == LEFT){ //bouton GAUCHE
    //Déplacement du paddle à gauche
    xPaddle = xPaddle - 10; 
    }
  }
  
  //Le paddle ne sort pas de l'écran par les côtés 
   if (xPaddle > width) 
   xPaddle = width;
   if (xPaddle < 0) 
   xPaddle = 0;
  
  //Je dessine mon paddle 
  fill(255); 
  stroke(255); 
  rectMode(CENTER);
  rect(xPaddle,yPaddle,200,10); 
  
  //Ma balle rebondit sur le paddle   
    if ((xPaddle - Paddle) < xBalle && (xPaddle + Paddle) > xBalle && 
    (yPaddle - 10) < yBalle && (yPaddle) > yBalle) {
    // Si la balle rebondit sur le paddle, inverse la vitesse 
    ySpeed = - ySpeed;
  }
  
  //Je dessine mes briques - boucle for 
  for (i=0; i<50; i++) {
    bx = i%10*110+10; 
    by = 40*(i/10)+10; 
    // Les briques apparaissent et sont dessinées si blocks[i]==1, elles disparaissent si blocks[i]==0
    if (blocks[i]==1) { 
      // Draw the block
      fill(255);
      stroke(0);
      rect(bx+100, by+10, bw, bh);
    }
    //Détection collision entre ma balle et les briques
    //Haut-bas des briques
    if(xBalle > (bx+10) && xBalle < (bx+90) &&
    yBalle > by && yBalle<(by+30) && blocks[i]==1){ //OK
      blocks[i]=0; //Disparition
      ySpeed = - ySpeed;
  }
    //Détection collision entre ma balle et côté 
   if (((xBalle > (bx-5) && xBalle < bx) || (xBalle > (bx+100) && xBalle < (bx+105))) &&
      yBalle > by && yBalle < (by+30) && blocks[i]==1) { //OK
      blocks[i]=0; //Disparition
      xSpeed = - xSpeed;
      }
      
    //Détection suite
    if (((xBalle > (bx-5) && xBalle < (bx+10)) || (xBalle > (bx+100) && xBalle < (bx+90))) &&
      yBalle > by && yBalle <(by+30) && blocks[i]==1) { //OK
      blocks[i]=0; //Disparition
      xSpeed = - xSpeed; 
      ySpeed = - ySpeed;
  }
  }
}

I think that the disfunctioning comes from here :

//Détection collision entre ma balle et les briques
    //Haut-bas des briques
    if(xBalle > (bx+10) && xBalle < (bx+90) &&
    yBalle > by && yBalle<(by+30) && blocks[i]==1){ //OK
      blocks[i]=0; //Disparition
      ySpeed = - ySpeed;
  }
    //Détection collision entre ma balle et côté 
   if (((xBalle > (bx-5) && xBalle < bx) || (xBalle > (bx+100) && xBalle < (bx+105))) &&
      yBalle > by && yBalle < (by+30) && blocks[i]==1) { //OK
      blocks[i]=0; //Disparition
      xSpeed = - xSpeed;
      }
      
    //Détection suite
    if (((xBalle > (bx-5) && xBalle < (bx+10)) || (xBalle > (bx+100) && xBalle < (bx+90))) &&
      yBalle > by && yBalle <(by+30) && blocks[i]==1) { //OK
      blocks[i]=0; //Disparition
      xSpeed = - xSpeed; 
      ySpeed = - ySpeed;
  }
  }

But I am not sure about it. What do you guys think?

Thanks again!

1 Like

please try to redo
paddle and brick collision without

rectMode(CENTER);

and remember then the paddle is touched by ball at px … px + pw // py - ball_r
and the bricks at bx … bx + bw // by+bh + ball_r

Alright as you said, I redid it without rectMode(CENTER);

I redid the bricks, they seem to be ok for now but I now have a problem between the paddle and the ball, the collision only happens on the edges of the paddle.

As you said, I should adapt this

if ((xPaddle - Paddle) < xBalle && (xPaddle + Paddle) > xBalle && 
    (yPaddle - 10) < yBalle && (yPaddle) > yBalle) {
    // Si la balle rebondit sur le paddle, inverse la vitesse 
    ySpeed = - ySpeed;
  }

not forgetting

and remember then the paddle is touched by ball at px … px + pw // py - ball_r

But it is not making any difference when I try to adapt the paddle. Am I doing it wrong? How should it be then?

Thank you!

sorry, as a next step i would use array for the brick positions too

int[] blocks  = new int[50];
int[] blocksx = new int[50];
int[] blocksy = new int[50];
int bh = 30; //Hauteur 
int bw = 100; //Largeur
int boff = 10;

void setup() {
  size(1200, 800);
  for (int i=0; i<50; i++) {
    blocks[i] = 1;
    blocksx[i] =  i%10*(bw + boff) + 50; 
    blocksy[i] =  floor(i/10) * ( bh + boff) + 20;
  }
}

void draw() {
  for (int i=0; i < 50; i++) {
    if (blocks[i]==1) { 
      fill(255);
      stroke(0);
      rect(blocksx[i], blocksy[i], bw, bh);
    }
  }
}

you see how easy it makes the drawing,
sure it will help with the collision

for the paddle,
you have

int Paddle = 100; 
// but
 rect(xPaddle,yPaddle,200,10); 
//
    if ((xPaddle - Paddle) < xBalle && (xPaddle + Paddle) > xBalle && 
    (yPaddle - 10) < yBalle && (yPaddle) > yBalle) {

//

you are confusing yourself with this settings
possibly also comes from some rectMode(CENTER) thinking??

1 Like