GP32 Breakout Collision


JyCet

Member
Joined
Feb 23, 2004
Messages
469
Age
118
Location
France
Website
Visit site
Hi all,

I've a big pb to make a good (see perfect) collision motor for a breakout game.
A ball have a variable speed and a variable angle, does someone have already study a good collision methode for a breakout game ?

Here a sample of my bad collision code <_<
Code:
void collision2()
{
  for (i=0;i<nb_brk;++i)
      if (brique.etat[i])
	{
  if ((balle.x>brique.x[i]-4)&&(balle.x<brique.x[i]+16)&&(balle.y>brique.y[i]-4)&&(balle.y<brique.y[i]+8))
  {
  if (balle.old_y>balle.y) // balle monte
  	//for (k=balle.old_y;k<balle.y;--k)
  	{
    if (balle.old_x>balle.x) // gauche
      {
      	if ((balle.y>brique.y[i])&&(balle.y<brique.y[i]+8)) //touche en bas
      	{
        balle.signe_y = 1;
        balle.y = k;
        flag_collision=1;
      	}
      	if ((balle.x>brique.x[i])&&(balle.x<brique.x[i]+16)) // touche a droite
      	{
        balle.signe_x = 1;
        balle.x=l;
        flag_collision=2;
      	}
      	brique.etat[i]=0;
      	//break;
      }
    else if (balle.old_x<balle.x) // droite
      {
      	if ((balle.y>brique.y[i])&&(balle.y<brique.y[i]+8)) //touche en bas
      	{
        balle.signe_y = 1;
        balle.y = k;
        flag_collision=3;
      	}
      	if ((balle.x>brique.x[i]-4)&&(balle.x<brique.x[i]+12)) // touche a gauche
      	{
        balle.signe_x = -1;
        balle.x=l;
        flag_collision=4;
      	}
      	brique.etat[i]=0;
      }
  	}
  else if (balle.old_y<balle.y) // balledescend
  	{
    if (balle.old_x>balle.x) // gauche
      {
      	if (balle.y==brique.y[i]) //touche en haut
      	{
        balle.signe_y = -1;
        balle.y = k;
        flag_collision=5;
      	}
      	if (balle.y==brique.x[i]+16) // touche a droite
      	{
        balle.signe_x = 1;
        balle.x=l;
        flag_collision=6;
      	}
      	brique.etat[i]=0;
      }
    else if (balle.old_x<balle.x) // droite
      {
      	if (balle.y==brique.y[i]) //touche en haut
      	{
        balle.signe_y = -1;
        balle.y = k;
        flag_collision=7;
      	}
      	if (balle.x==brique.x[i]) // touche a gauche
      	{
        balle.signe_x = 1;
        balle.x=l;
        flag_collision=8;
      	}
      	brique.etat[i]=0;
      }                                 
  	}
  }

	}
}


Thk in advance
 
Well, that's quite simple. Let's just consider that the wall has his own angle. For instance, a vertical wall will have an angle of PI/2 or -PI/2. You just take the one that is closest to the ball's, then :
Code:
b: ball initial angle
w1: first wall angle (the closest from the ball's)
w2: second wall angle (first + PI)
f: ball final angle

f=w2-(w1-B)
Of course, you can simplify the formula, but this one is pretty easy to understand.
For the distance :
s: speed (distance in pixel of the ball point between two frames)
i: ball initial distance from collision point
f: final distance from collision point
f=s-i
edit: code tags, smileys ain't funny in mathematics.

These are angles formulas. For the collision algorithm:
A ball will only collide a wall if it's near enough, and if the direction is the good one. So you just have the check wall distance, then if it's near enough, check the angle, and if it's the good direction, call the rebound code ;)
That can be done with a loop going through an array containing parameters of the walls and another with the brick. The remote bricks don't have to be checked, don't forget it ;)
 
I did a breakout clone in VB. What I did is create some cases (6 i think) and if the ball was going up and right and hit the right wall it would then call the case to go up and left. Probably shit programming but its how I did it :/
 
@damaki:

Je n'ai pas de probleme d'angle de reflection ou de variation de vitesse pour le deplacement et les rebonds de la balle (je peux lui faire faire des cercles si je veux :p ), mais des pbs de detection de collision type bounding box entre la balle et les briques.

~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

I just have bounding box collision problem

Here my last bouniding box collision for breakout, but always some bug :(

Code:
void collision2()
{
  for (i=0;i<nb_brk;++i)
      if (brique.etat[i])
	{
  GpBitBlt(NULL,&gpDraw[nflip],brique.x[i],brique.y[i],16,8,(unsigned char*)tiles_jeu,brique.etat[i],0,176,8);
  if ((balle.x>brique.x[i]-6)&&(balle.x<brique.x[i]+18)&&(balle.y>brique.y[i]-6)&&(balle.y<brique.y[i]+10))
  {
  if (balle.signe_y==-1) // balle monte
  	{
    if (balle.signe_x==-1) // gauche
      {
      	// touche en bas
      	for (j=0;j<6;++j)
        if ((balle.y==brique.y[i]+4+j)&&(balle.x<brique.x[i]+13+j)&&(balle.x>brique.x[i]+3-j))
      	{
        balle.signe_y = 1;
        balle.y = k;
        flag_collision=1;
        break;
      	}
      	// touche a droite
      	for (j=0;j<6;++j)
        if ((balle.x==brique.x[i]+12+j)&&(balle.y<brique.y[i]+3+j)&&(balle.y>brique.y[i]+3-j))
      	{
        balle.signe_x = 1;
        balle.x=l;
        flag_collision=2;
        break;
      	}
      	brique.etat[i]=0;
      }
    else if (balle.signe_x==1) // droite
      {
      	// touche en bas
      	for (j=0;j<6;++j)
        if ((balle.y==brique.y[i]+4+j)&&(balle.x<brique.x[i]+13+j)&&(balle.x>brique.x[i]+3-j))
      	{
        balle.signe_y = 1;
        balle.y = k;
        flag_collision=3;
        break;
      	}
      	// touche a gauche
      	for (j=6;j>0;--j)
        if ((balle.x==brique.x[i]-j)&&(balle.y<brique.y[i]+8+j)&&(balle.y>brique.y[i]-j))
        {
        	balle.signe_x = -1;
        	balle.x=l;
        	flag_collision=4;
        	break;
        }
      	brique.etat[i]=0;
      }
  	}
  else if (balle.signe_y==1) // balle descend
  	{
    if (balle.signe_x==-1) // gauche
      {
      	// touche en haut
      	for (j=6;j>0;--j)
        if ((balle.y==brique.y[i]-j)&&(balle.x<brique.x[i]+16+j)&&(balle.x>brique.x[i]-j))
      	{
        balle.signe_y = -1;
        balle.y = k;
        flag_collision=5;
        break;
      	}
      	// touche a droite
      	for (j=0;j<6;++j)
        if ((balle.x==brique.x[i]+12+j)&&(balle.y<brique.y[i]+3+j)&&(balle.y>brique.y[i]+3-j))
      	{
        balle.signe_x = 1;
        balle.x=l;
        flag_collision=6;
        break;
      	}
      	brique.etat[i]=0;
      }
    else if (balle.signe_x==1) // droite
      {
      	// touche en haut
      	for (j=6;j>0;--j)
        if ((balle.y==brique.y[i]-j)&&(balle.x<brique.x[i]+16+j)&&(balle.x>brique.x[i]-j))
      	{
        balle.signe_y = -1;
        balle.y = k;
        flag_collision=7;
        break;
      	}
      	// touche a gauche
      	for (j=6;j>0;--j)
        if ((balle.x==brique.x[i]-j)&&(balle.y<brique.y[i]+8+j)&&(balle.y>brique.y[i]-j))
      	//if ((balle.x>brique.x[i]-4)&&(balle.x<brique.x[i]+2)) // touche a gauche
        {
        	balle.signe_x = 1;
        	balle.x=l;
        	flag_collision=8;
        	break;
        }
      	brique.etat[i]=0;
      }                                 
  	}
  }

	}
}

Thk for all.
 
If you want to make a true bounding box collision detection algorithm this isn't for you, but if you want a very very fast method (compared to bounding box), just make a tilemap the size of the ball. Then you can just index in for the ball's location. The actual blocks may have to take up more then one "tile", and there may be one pixel error depending on how round the ball is.
 
i'd do a "seperate axis bounding box + pixel perfect if bb col found" check.

and it's not only a helluva stupid name, it's really the way i'd do it.
 
Thanks to everybody,

my best solution for a breakout collision detection is to use 2 bounding box.
So i've tested it and i'm happy with the result :)

here the code :

Code:
void collision()
{
  for (i=0;i<nb_brk;++i)
      if (brique.etat[i])
	{
  if ((balle.x>brique.x[i]-6)&&(balle.x<brique.x[i]+18)&&(balle.y>brique.y[i]-5)&&(balle.y<brique.y[i]+10))
  {
  if (balle.signe_y==-1) // balle monte
  	{
    if (balle.signe_x==-1) // gauche
      {
      	// touche en bas
      	if ((balle.x<brique.x[i]+16)&&(balle.x>brique.x[i]-3)
        &&(balle.y<brique.y[i]+10)&&(balle.y>brique.y[i]+3))
      	{
        balle.signe_y = 1;
        brique.etat[i]=0;
      	}
      	// touche a droite
      	if ((balle.x<brique.x[i]+18)&&(balle.x>brique.x[i]+12)
        &&(balle.y<brique.y[i]+9)&&(balle.y>brique.y[i]-2))
      	{
        balle.signe_x = 1;
        brique.etat[i]=0;
      	}
      }
    else if (balle.signe_x==1) // droite
      {
      	// touche en bas
      	if ((balle.x<brique.x[i]+15)&&(balle.x>brique.x[i]-4)
        &&(balle.y<brique.y[i]+10)&&(balle.y>brique.y[i]+3))
      	{
        balle.signe_y = 1;
        brique.etat[i]=0;
      	}
      	// touche a gauche
      	if ((balle.x<brique.x[i])&&(balle.x>brique.x[i]-6)
        &&(balle.y<brique.y[i]+9)&&(balle.y>brique.y[i]-2))
      	{
        balle.signe_x = -1;
        brique.etat[i]=0;
      	}
      }
  	}
  else if (balle.signe_y==1) // balle descend
  	{
    if (balle.signe_x==-1) // gauche
      {
      	// touche en haut
      	if ((balle.x<brique.x[i]+16)&&(balle.x>brique.x[i]-3)
        &&(balle.y<brique.y[i])&&(balle.y>brique.y[i]-5))
      	{
        balle.signe_y = -1;
        brique.etat[i]=0;
      	}
      	// touche a droite
      	if ((balle.x<brique.x[i]+18)&&(balle.x>brique.x[i]+12)
        &&(balle.y<brique.y[i]+7)&&(balle.y>brique.y[i]-4))
      	{
        balle.signe_x = 1;
        brique.etat[i]=0;
      	}
      }
    else if (balle.signe_x==1) // droite
      {
      	// touche en haut
      	if ((balle.x<brique.x[i]+15)&&(balle.x>brique.x[i]-4)
        &&(balle.y<brique.y[i])&&(balle.y>brique.y[i]-5))
      	{
        balle.signe_y = -1;
        brique.etat[i]=0;
      	}
      	// touche a gauche
      	if ((balle.x<brique.x[i])&&(balle.x>brique.x[i]-6)
        &&(balle.y<brique.y[i]+7)&&(balle.y>brique.y[i]-4))
      	{
        balle.signe_x = -1;
        brique.etat[i]=0;
      	}
      }                                 
  	}
  }

	}
}

Now i'm return on the road to continu coding B)
 
Very funny JyCet, because the first thing I did when I was hired by my previous company was a breakout clone. And the algorithm was pretty similar to what you showed here ... I had to learn Java so I thought it was a good idea to write a game applet ;) I guess there are not 36 ways of doing it.

_tyrell_
 
Back
Top