Sign in to follow this  

breakout collision bug

This topic is 4306 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

I'm trying to make a breakout clone, I have a bug with the collisions. I'm working in Cpp, for collision I have all the sprites stored in a Vector, then iterate through them using bounding rectangles to check for collisions. When the ball and a brick collide, I use the bounding rects again see which side the ball hit. If it hits the top or bottom I flip the Y direction, if it hits either side I flip the X direction. Here is the problem, when the ball hits 2 bricks(unbreakable bricks) it gets stuck inside them. The ball has to hit the bricks right where they meet, where the edges are together. I've tried a couple different ways of determining which way the ball should bounce, but none of them fix the problem. Here is one approach I've tried.
if(( BallCenter.x > rcBrick.left) && (BallCenter.x < rcBrick.right))
	pBall->Bounce(1,-1);
else if(( BallCenter.y > rcBrick.top) && (BallCenter.y < rcBrick.bottom))
	pBall->Bounce(-1,1)
Here is a link to the exe, the sliver bricks are unbreakable, the mouse button releases the ball. Any ideas here? Do I need to implement a new collision system?

Share this post


Link to post
Share on other sites
Heya Rob,

I'd love to help you solve this problem, but without a bit futher information I'm at a loss. I can tell you that you do NOT need to implement a new collision system. It sounds like your logic is pretty solid in general, you're probably just missing a case or two.

With your current collision system you might need to be careful of corners because they count as both horizontal and vertical collisions. It might be that you're always treating a collision with a corner as a vertical collision, when in fact they are sometimes horizontal.

My advice is do something much like you're doing now...when you detect a collision with a corner, check the larger angle....is the ball moving up/down primarily or left/right primarily. Then adjust the appropriate (x or y) direction as seems reasonable. The corners would be the only place this would be a problem, because only corners can count as both horizontal and vertical surfaces.

Cheers!

Share this post


Link to post
Share on other sites
It sounds to me like you're colliding with both brick corners. You hit the first corner, and the ball flips, say, its X velocity (if you check for X collisions before Y collisions, for example). Then you hit the second corner in the same frame, so the ball flips its X velocity again! Now it's going back in the same direction it was before you ran collision detection. In the next frame, it'll just bury itself further inside of one of the bricks, and then it's all over.

I'd recommend two changes: first, correctly handle corner collisions. You can roughly approximate this by flipping the ball's velocity vector across a 45-degree angle (the "perpendicular" of the corner of the brick). Second, find some way to detect when two bricks form a continuous surface, and treat them as a single brick for purposes of determining new velocities.

Share this post


Link to post
Share on other sites
Thanks for the suggestions.
I agree that the corner collision needs the attention. If I include a corner scenario then occasionally the ball will act as if the middle of a row has a corner. So determining if there is a block next to the current one would allow me to treat it as one big block. I could make a function that cycles thru the vector container checking that, but it seem like it would be a lot of extra cpu power(accepting that pc now could handle this, I feel like there should be an easier/smarted way) What I've done now is to:
1)set the ball back one frame
2)check the horizontal bounce first, if it's not a horz., then it must be a vertical (I know this ignores the corner bounce, but it's a compromise I'm willing to accept for now.

if( ( BallCenter.y < rcBrick.top) || (BallCenter.y > rcBrick.bottom))
pBall->Bounce(1,-1);
else
pBall->Bounce(-1,1);


This works for right now, there is the ocassional anomaly when there is a vertical bounce, but for now I can deal.

Thanks again for the help.

Share this post


Link to post
Share on other sites
You don't really want an 'else' to check x then y as it means you could only ever collide off of one axis at a time, you want to check the 2 axis independently and alter the movement for those axis.

Something like this??

if(( BallCenter.x > rcBrick.left) && (BallCenter.x < rcBrick.right))
{
BounceXAdd=-BounceXAdd;
}

if(( BallCenter.y > rcBrick.top) && (BallCenter.y < rcBrick.bottom))
{
BounceYAdd=-BounceYAdd;
}


Remember to take into account the width of your ball as well,

Paul

Share this post


Link to post
Share on other sites

This topic is 4306 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this