Collision Detection Problem

Started by
3 comments, last by Cornutopia 19 years, 7 months ago
I am sure eveyone is tired of hearing about collision detection, but I have a pickle of a situation. I am making a breakout clone, and am having issues with the collision dection of the blocks. I use the same collision checks as I do for the paddle, but everything goes crazy when I enable the block collision detection. Here is my code: Map.cpp (collision Detection code)

int Map::collision(Ball cBall)
{
	int rType;

	for (int r = 0;r < MAPSIZER; r++)
	{
		for (int c =0;c < MAPSIZEC;c++)
		{
			if(level[r][c].isAlive()==1)
			{
				rType = level[r][c].collision(cBall);
				return rType;
			}
		}
	}	

	return 0;
}

Player.cpp (Collision Detection code)

int Player::collision(Ball cBall)
{
if((position.y+height)>(cBall.getPositionY()-cBall.getHeight())) 
	{	
		if((position.x+width) > (cBall.getPositionX()-cBall.getWidth()) &&
		   (position.x-width) < (cBall.getPositionX()+cBall.getWidth()))
		{return 3;}
	}
	return 0;
}

Ball.cpp (Collision Detection code)

int Ball::collision(int D)
{
	if(position.x >=  5.40f-width) {xdirection = -1.0f; return true;}
	if(position.x <= -5.45f+width) {xdirection =  1.0f; return true;}
	if(position.y >=  7.50f-height){ydirection = -1.0f; return true;}
	if(position.y <= -8.00f+height){ydirection =  1.0f; return true;}

	switch(D)
	{
	case 0:
		return false;
		break;
	case 1:
		ydirection = -1;
		return true;
		break;
	case 2:
		xdirection =  1;
		return true;
		break;
	case 3:
		ydirection =  1;
		return true;
		break;
	case 4:
		xdirection = -1;
		return true;
	default:
		return false;
		break;
	}
}

game loop code

	ball.collision(map.collision(ball));
	ball.collision(player.collision(ball));
	ball.update();

	map.drawMap();
	player.drawPlayer();
	ball.drawBall();

Right now I just have the code for TOP detection for the blacks. (one step at a time :)) If I disable the block collision, it works fine with the paddle, but when I enable it, the ball does erratic things. Thanks, dimebag
Advertisement
ok, im not sure what that D switch is, but i have a few quesions, How are you changing the velocity of the ball when it hits something? just use the same algorithim you used when the ball hits the sides, except you have to determine which side of a brick you hit.

also, your collision function you are calling in the MAp.cpp belongs to the level class, and both of the classes you provided with collision detection are not the level class.
OK, it might be a bit confusing at first but it makes sence to me atleast.

The collision for the block is done in the block class, but called from the map class, where the level array that contains the blocks is. The ball class is passed to each collision case so that there is a point of reference. What ever is returned( 1-4) determins the direction of the ball (Up, Down, Left or Right - The switch statment in the ball class). I did not include the code in the block class to collide with the sides or bottom. Just the top.

Now the issue is that when the block collision is enabled, the ball will go to the top of the screen and just go up and down really fast, almost like it is traveling a stright line at the top. Just back and forth. I am at my wits end with it, and about to start from scratch.

The int D, is the return for the direction (big D) the ball travels.

ala
int Ball::collision(int D){	if(position.x >=  5.40f-width) {xdirection = -1.0f; return true;}	if(position.x <= -5.45f+width) {xdirection =  1.0f; return true;}	if(position.y >=  7.50f-height){ydirection = -1.0f; return true;}	if(position.y <= -8.00f+height){ydirection =  1.0f; return true;}	switch(D)	{	case 0:		return false;		break;	case 1:		ydirection = -1;		return true;		break;	case 2:		xdirection =  1;		return true;		break;	case 3:		ydirection =  1;		return true;		break;	case 4:		xdirection = -1;		return true;	default:		return false;		break;	}}


Any suggestions are helpful.

dimebag
that jiggling effect happens because the ball collides each frame once it gets to that point (maybe because of floating point innaccuracy, or some other very small error in the calculations).

an easy (but not exactly correct math-and-physics-wise) solution is to move the position of the ball back outside the brick/wall, and also reverse the direction. for example, when the ball collides with the top of the board, instead of just reversing the y-velocity, move the ball back into the board and then reverse the y-velocity. that way, it won't detect the collision again next frame, before it has moved back.

to be more precise (it may or may not look better, but it won't look worse) you'd have to calculate where the ball collided exactly, and then calculate where the ball would have bounced to since then (and place it at that position, with its new velocity).

i hope i made enough sense to help.
--- krez ([email="krez_AT_optonline_DOT_net"]krez_AT_optonline_DOT_net[/email])
Quote:Original post by krez
an easy (but not exactly correct math-and-physics-wise) solution is to move the position of the ball back outside the brick/wall, and also reverse the direction. for example, when the ball collides with the top of the board, instead of just reversing the y-velocity, move the ball back into the board and then reverse the y-velocity. that way, it won't detect the collision again next frame, before it has moved back.


That IS physically correct. Matter does not intersect matter in real life! Seriously, this is the correct way to do it when it comes to any collision detection. Always move the two objects apart to the border point of collision before you change the velocities. Never permit virtual matter to intersect or leap over other virtual matter (like real life!)

Mark
Ever wanted to command a starship?
http://www.lostinflatspace.com
Sound Effects For Game Developers
http://www.indiesfx.co.uk

This topic is closed to new replies.

Advertisement