How to implement better Collision detection

Started by
15 comments, last by Khatharr 11 years ago

I have experience implementing basic collision detection using bounding box collision with the help of the rectangle objects from the Java API.

The bounding box collision is fine for objects like rectangle shaped objects(ie: rows of bricks in a game). But things got more complex when I start adding objects that are not shaped like a rectangle (ie: a circle or even more complex object: a bird).

Seeing as my game uses images to depict non-rectangular shaped creatures, bounding boxes will not look right on these creatures. With bounding box collision detection, there will be a situation like the one below when an intersection will happen between both rectangles(the monster bounded by a rectangular collision box and a laser projectile also bounded by a rectangular collision box. From a visual standpoint, it is a game immersion breaking problem.

collbox_zpscbf88de3.png

What type of programming techniques or perhaps I need to learn or apply some new math concepts for this problem?

Advertisement

You should always make the collision box smaller than the actual graphic of the entity, which will avoid a lot of situations like the one you described, even if occasionally it will cause entities' graphics to overlap without collision. That being said, there are methods for using circles instead of rectangles for collision detection, as well as per pixel collision - though both methods are more costly than rectangle collision. A tutorial for circle collision can be found here, though this one is written in C++.

circle collision is extremely cheap(it's simply (distance between center points)<=(sum of both radius)). Although not as cheap as AABB, it's pretty much a non performance issue for general collisions detection. remember that you can also use AABB's to surround the entire object for initial collision checking, then use finer collision checking.

for shapes that don't conform to circles or rectangles, you could use a several smaller aabb's/circles that better represent the shape of the object's.
Check out https://www.facebook.com/LiquidGames for some great games made by me on the Playstation Mobile market.

Well you could switch to bounding spheres instead of boxes - to check if objects collide just give them each a radius then find the distance between the two center points

( distance = sqrt( xDistance2 + yDistance2) ) and if it is less than the two objects' radius' added together then there has been a collision

also you can define a bouding ellipse so that the y radius is different than the x radius - the math is a bit more complicated but the bounding ellipse would most likely match your object pretty well.. you can define an x radius for the object and a y radius for the object - then find the angle between the two objects and determine if there was a collision for the objects' radius length at that angle.. You can do that in the following way..

first find the angle between the two objects' center points by using..


float angle = atan( yDistanceApart / xDistanceApart )

then you can find each objects radius using this angle...

to do that consider the ellipse formula

( x2 / xRadius2 ) + ( y2 / yRadius2 ) = 1

now consider

x = radius * cosf(angle) and y = radius * sinf(angle)

substituting in the ellipse equation and solving for the radius you get

radius = sqrtf( (xRadius2 * yRadius2) / ( cosf2(angle) * yRadius2 + sinf2(angle) * xRadius2) )

so you find the radius at that angle for both objects and then you can again see if the distance between them is less then their radi added together.. if it is less then there is a collision

You should always make the collision box smaller than the actual graphic of the entity, which will avoid a lot of situations like the one you described, even if occasionally it will cause entities' graphics to overlap without collision. That being said, there are methods for using circles instead of rectangles for collision detection, as well as per pixel collision - though both methods are more costly than rectangle collision. A tutorial for circle collision can be found here, though this one is written in C++.

Make the collision box smaller. Hmm...I will try that. I guess that means I need to make my own custom collision box instead of the Rectangle object from the Java API. Thanks for the advice. smile.png

You could have an ellipse shaped bound on the ellipse shaped smiley monster. It's a bit complicated but this article explains a very simple way of converting this into a sphere box text which are quite simple and cheap. This way you could have a perfect bound for the ellipse smiley monster.

I'm not sure if this is true or not but it doesn't help with any ellipse - ellipse testing nor sphere - ellipse testing (except they're both have the same axes and orientation, I guess).

You could have an ellipse shaped bound on the ellipse shaped smiley monster. It's a bit complicated but this article explains a very simple way of converting this into a sphere box text which are quite simple and cheap. This way you could have a perfect bound for the ellipse smiley monster.

I'm not sure if this is true or not but it doesn't help with any ellipse - ellipse testing nor sphere - ellipse testing (except they're both have the same axes and orientation, I guess).

The post I made earlier literally walks through how to do ellipse collision detection step by step

Make the collision box smaller. Hmm...I will try that. I guess that means I need to make my own custom collision box instead of the Rectangle object from the Java API. Thanks for the advice.

You don't need to make your own rectangle - just use the center point of the sprite ( width / 2 and height / 2) and use either bounding sphere or ellipse. Both are very quick and easy to implement - especially bounding sphere.

You don't need to make your own rectangle - just use the center point of the sprite ( width / 2 and height / 2) and use either bounding sphere or ellipse. Both are very quick and easy to implement - especially bounding sphere.

I can't find an equivalent class that resembles a bounding sphere or ellipse in the Java API. The thing that came close was Ellipse2D but that was an abstract class which would mean it cannot be instantiated.

irst find the angle between the two objects' center points by using..


float angle = atan( yDistanceApart / xDistanceApart )

then you can find each objects radius using this angle...

Never use atan in this situation, when it is so goddamn simple to just write:


float angle = atan2( yDistanceApart, xDistanceApart )

And so much more correct.

I can't find an equivalent class that resembles a bounding sphere or ellipse in the Java API. The thing that came close was Ellipse2D but that was an abstract class which would mean it cannot be instantiated.

You don't need a class to represent it - just store the radius length you want for the object - if the distance between the two objects center points is less than the two objects radi added together then collision has happened.

and yes - use the ever so much more correct atan2 instead of atan

This topic is closed to new replies.

Advertisement