Collision function
I am making a small breakout-style game.
I have a collision function that detects if the ball and a brick collides but I need to detect which side its hiting so the ball can bounce in the correct direction.
What is the best way to do this?
I have tried some ways but all falls because the ball collides with the underside at the same time as the side.
May 09, 2001 02:15 PM
if it collides with more than one side of the brick then you should have an extra test to determine which side is closer..if they''re both the same(ball hit a corner dead-on)then bounce off diagonally(plus offset the angle of the ball)..
You could always do 4 collision detections for each block, one for each side. I know this would slow it down a little but in a breakout game, where you only have 1 ball that''s doing the colliding (maybe 2 or more at multiball stage but not exactly 100+) so it shouldn''t matter too much.
Thanks for the help but Im still not able to make it work. There must be dozens of people out there who has made a Breakout-style game. Maybe somebody could supply me with a code sample of thier collision function?
When I first started out I wrote a breakout game and had the same question. Like many little projects I did back then, I never completed it and I never did finish off this particular problem. Nowadays it''s one of those ''If I knew then what I knew now'' sort of things.
What you need to be thinking of is circle vs 2D box tests. You have already mentioned that you have managed to determine if these are colliding, so I won''t go into that detecting the collision.
Think of the bat as a rectangle made up of four line segments. Each line segment has a normal pointing outwards, but these normals are very straight forward and don''t require any computation. If the top left of your screen is (x=0,y=0) the the normals are top side = (0, -1), left = {-1, 0 }, right = { 1, 0 } and bottom =( 0, 1 ). If your screen co-ordinate system is flipped the other way then simply negate Y values in each normal.
That gives your four line segments, each with a normal. The first thing you should do is use the normal to reject tests against sides that are not facing the direction of ball travel with a simple dot product test. There is no need to consider collisions against such lines, because clearly the ball would have collided with sides that it is facing first.
This will leave you with one or two tests to perform. One, if the ball is approaching a side, face on (the above dot product would have rejected the other three sides) and two if the ball is
travelling even slightly diagonally.
Next you want to determine which part of the ball (the circle) hit the remaining sides first. You need to do this calculation for all the remaining sides. Again, we use the normal for this.
Take the normal of the side you are colliding against, multiply it by the radius of the ball and add it to the position of the balls centre (before the ball was moved). The resulting position is the position on the circle (in it''s previous frame) that first hit the line.
Now make a line from that position in the direction that the ball was travelling (start = the point on the circle, end = the point + velocity vector). Perform a line intersection test. If the point of intersection of these two lines is within the line segment of that side and not beyond the extents then your ball did hit that side and at that point of intersection. If not, test any other remaining sides.
If you have still not found a collision, then the ball collided beyond the extents of all the line segments that form the sides. This means you hit the corner. In this case just negate the direction of travel to make it bounce in the opposite direction, but if you wished to go into more accuracy (there is no need with breakout) you could fire a ray from the said corner in the opposite direction of travel and test where it intersects the circle in it''s old position and bounce of the tangent to that point.
A good page for you to look at 2D line intersections maths is Paul Bourkes geometry page @ http://astronomy.swin.edu.au/pbourke/geometry/ whilst bearing in mind that your are dealing with line segments, so testing if the intersection point is outside of 0.0 and 1.0 of the line segment does give you the answer as to whether or not it hit the line segment or the extended line.
The same collision test also applies to your bricks.
What you need to be thinking of is circle vs 2D box tests. You have already mentioned that you have managed to determine if these are colliding, so I won''t go into that detecting the collision.
Think of the bat as a rectangle made up of four line segments. Each line segment has a normal pointing outwards, but these normals are very straight forward and don''t require any computation. If the top left of your screen is (x=0,y=0) the the normals are top side = (0, -1), left = {-1, 0 }, right = { 1, 0 } and bottom =( 0, 1 ). If your screen co-ordinate system is flipped the other way then simply negate Y values in each normal.
That gives your four line segments, each with a normal. The first thing you should do is use the normal to reject tests against sides that are not facing the direction of ball travel with a simple dot product test. There is no need to consider collisions against such lines, because clearly the ball would have collided with sides that it is facing first.
This will leave you with one or two tests to perform. One, if the ball is approaching a side, face on (the above dot product would have rejected the other three sides) and two if the ball is
travelling even slightly diagonally.
Next you want to determine which part of the ball (the circle) hit the remaining sides first. You need to do this calculation for all the remaining sides. Again, we use the normal for this.
Take the normal of the side you are colliding against, multiply it by the radius of the ball and add it to the position of the balls centre (before the ball was moved). The resulting position is the position on the circle (in it''s previous frame) that first hit the line.
Now make a line from that position in the direction that the ball was travelling (start = the point on the circle, end = the point + velocity vector). Perform a line intersection test. If the point of intersection of these two lines is within the line segment of that side and not beyond the extents then your ball did hit that side and at that point of intersection. If not, test any other remaining sides.
If you have still not found a collision, then the ball collided beyond the extents of all the line segments that form the sides. This means you hit the corner. In this case just negate the direction of travel to make it bounce in the opposite direction, but if you wished to go into more accuracy (there is no need with breakout) you could fire a ray from the said corner in the opposite direction of travel and test where it intersects the circle in it''s old position and bounce of the tangent to that point.
A good page for you to look at 2D line intersections maths is Paul Bourkes geometry page @ http://astronomy.swin.edu.au/pbourke/geometry/ whilst bearing in mind that your are dealing with line segments, so testing if the intersection point is outside of 0.0 and 1.0 of the line segment does give you the answer as to whether or not it hit the line segment or the extended line.
The same collision test also applies to your bricks.
This topic is closed to new replies.
Advertisement
Popular Topics
Advertisement
Recommended Tutorials
Advertisement