BREAKOUT Project - Help with collision detection

This is actually very confusing.

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

//

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
 rect(xPaddle,yPaddle,200,10); 
//
    if ((xPaddle - Paddle) < xBalle && (xPaddle + Paddle) > xBalle && 
    (yPaddle - 10) < yBalle && (yPaddle) > yBalle) {

//```

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 
int Paddlew = 200; 
int Paddleh = 10; 

rect(Paddlex, Paddley, Paddlew, Paddleh); 
circle(Ballex,Balley,2*Baller);

if (Paddlex  < Ballex && (Paddlex + Paddlew) > Ballex && 
  (Paddley - Baller) < Balley && Paddley > Balley) {}
//
  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;
  }
  }

sorry, can 't read it,
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