# BREAKOUT Project - Help with collision detection

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

2 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;
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

int xPaddle = 600; //Position x
int yPaddle = 650; //Position y

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
} else if (keyCode == LEFT){ //bouton GAUCHE
}
}

//Le paddle ne sort pas de l'écran par les côtés

fill(255);
stroke(255);
rectMode(CENTER);

//Ma balle rebondit sur le paddle
// 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

``````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 &&
// 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;
int[] blocksx = new int;
int[] blocksy = new int;
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

you have

``````int Paddle = 100;
// but
//

//
``````

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

1 Like

This is actually very confusing.

``````int Paddle = 100;
// but
//

//
``````

I redid my code without the rectMode(CENTER) as you suggested. However, I used the rectMode(CENTER) in the first place in order to draw my paddle and my paddle isn’t working anymore.

I don’t know what to change in this code to make it work again :

``````int Paddle = 100;
// but
//

//`````````

sorry for all this rewriting, but that is how i can read it??

``````float Ballex = 650; //Position x
float Balley = 400; //Position y
int   Baller = 10;

int Paddlex = 600; //Position x
int Paddley = 650; //Position y

circle(Ballex,Balley,2*Baller);

//
for (int i=0; i < 50; i++) {
if (blocksx[i]  < Ballex && (blocksx[i] + bw) > Ballex &&
(blocksy[i] + Baller) < Balley && blocksy[i] > Balley) {}
}
``````

now rectangle thinks start left top
and circle in center

1 Like

Ok you were right. The way I did it was very confusing but what you just wrote about the paddle works perfectly. Thank you!

I know that you earlier suggested a different use of array for the brick positions but I would like to keep it the way I did so that I can really perfect this method and really understand what I am doing and what I started.

I still have a little problem with collision detection. Sometimes, the ball will hit a brick’ side and it won’t disappear at all which I find quite annoying.

I think that there is a problem with the distance covered but I am not quite sure. Is there anything that seems a little bit weird here?

``````//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+40, by+10, bw, bh);
}
//Détection collision entre ma balle et les briques
//Haut-bas des briques
if(xBalle > (bx+4) && xBalle < (bx+96) &&
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-1) && xBalle < (bx+5)) || (xBalle > (bx+95) && xBalle < (bx+101))) &&
yBalle > by && yBalle <(by+30) && blocks[i]==1) { //OK
blocks[i]=0; //Disparition
xSpeed = - xSpeed;
ySpeed = - ySpeed;
}
}
``````

what you try do here?
collision ball <–> brick from all brick sides?

but i have a idea for a easier testing:

``````Ballex = mouseX;
Balley = mouseY;
circle(Ballex,Balley,2*Baller);

``````
1 Like

I used a loop to draw 50 blocks (5 rows, 10 columns). Then I said ok, if blocks[i]==1, the block will appear. If blocks[i]==0, the block will disappear.

``````//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+40, by+10, bw, bh);
}
``````

If the ball come close to the top, bottom or sides and hit the block, then I reverse the speed and the block also disappear.

``````//Détection collision entre ma balle et les briques
//Detect collision top-bottom blocks
if(xBalle > (bx+4) && xBalle < (bx+96) &&
yBalle > by && yBalle<(by+30) && blocks[i]==1){ //OK
blocks[i]=0; //Disparition
ySpeed = - ySpeed;
}
//Detect collision sides
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;
}

if (((xBalle > (bx-1) && xBalle < (bx+5)) || (xBalle > (bx+95) && xBalle < (bx+101))) &&
yBalle > by && yBalle <(by+30) && blocks[i]==1) { //OK
blocks[i]=0; //Disparition
xSpeed = - xSpeed;
ySpeed = - ySpeed;
}
}
``````

sorry / other timezone /

-a- your ( xy ± npx ) is a result of not having clean position for each rectangle.
so i want you again to check my above ( ready code ) for the “make” bricks

-b- for ball / rect collision are many ways,
basic should be a OVER RECT
a concept you need again and again with processing
like mouse over rect ( button )…
we make a boolean function:

``````boolean overRect(float mx, float my, int x, int y, int w, int h) {
return ( mx > x && mx < x + w &&  my > y && my < y + h ) ;
}
``````

this returns true if the POINT at ( mx,my )
is over a rect(x,y,w,h)

ha, but a ball is not a point, it has a radius, what we do?
the ball hits the rect actually “earlier” by br
so we just think that the rect is BIGGER by br ON ALL SIDES
with this a hit condition would be

``````circle(bx,by,2*br);
rect(rx,ry,rw,rh);
//  println( overRect(bx,by,rx,ry,rw,rh) );  // point thinking
println( overRect(bx,by,rx-br,ry-br,rw+2*br,rh+2*br) ); // ball radius >> bigger rect / thinking
``````

all this works only if you NOT use rectMode(CENTER);

complete test code
``````int rx=20, ry=30, rw=60, rh=40;
int bx, by, br=10;

void setup() {
noFill();
}

void draw() {
background(200, 200, 0);
bx = mouseX;
by=mouseY;
circle(bx, by, 2*br);
rect(rx, ry, rw, rh);
//  println( overRect(bx,by,rx,ry,rw,rh) );  // point thinking
println( overRect(bx, by, rx-br, ry-br, rw+2*br, rh+2*br) ); // ball radius >> bigger rect / thinking
}

boolean overRect(float mx, float my, int x, int y, int w, int h) {
return ( mx > x && mx < x + w &&  my > y && my < y + h ) ;
}

``````

-c-
but you want also a change of speed of the ball, depending on what side of the rect it hits?
a easy first way can be ( later make it shorter and also check on the rect edges hit… )

``````
for (int i=0; i < 50; i++) {
if (blocks[i]==1) {
rect(rx[i], ry[i], rw, rh);
if (  overRect(bx,by,rx[i]-br,ry[i]-br,rw+2*br,rh+2*br) ) {
println("over block: "+i);
blocks[i]=0; //_disable
if ( by > ry[i] + rh )  ySpeed *= -1;  //     println("// ball come from bottom");
if ( by < ry[i]      )  ySpeed *= -1;  //     println("// ball come from top");
if ( bx < rx[i]      )  xSpeed *= -1;  //     println("// ball come from left");
if ( bx > rx[i] + rw )  xSpeed *= -1;  //     println("// ball come from right");
}
}
}
``````

Working great, thank you very much!

1 Like