GP32 Collision Detection


Drag

Member
Joined
Jan 11, 2004
Messages
371
Age
36
Location
USA
Website
drag.wootest.net
Now, I usually don't have a lot of problems with collision detection, but I'm having trouble with it now.

I can't figure out the best way to get it working! I'm talking about physics like balls bumping into each other and stuff.

I can't figure out how to tell which edge is bumping into an object.
When a ball falls onto a wall, for example, three sides are detected entering the wall: the bottom edge, the left edge, and the right edge.

So the way I'm doing it now, the ball would bounce, but it'd also stop, as though it bumped into a wall on both edges.

If the ball moved right and bumped into a wall, the bottom, top, and right edge would all detect a collision, so the ball would bounce off of the wall, and bounce upward, as though it hit the floor.

So I need a way to detect which specific edge(s) is/are actually passing into the wall.

When the ball is moving down and right, when it hits the floor, I want it to detect that as a collision with the bottom edge of the ball, as opposed to a collision with the bottom, right, and left edge.

Can anyone help? I'm not very experienced in video game physics.

This is for my Incredible Machine clone, by the way.
 
I really don't know how I woukd do it, but I think it's not enough to control the four edges of your ball as you can hit a corner of an object and in this case it's not just an up/down/left/right edge of the ball that will be in contact with the wall.

Perhaps you should make your calculations from the center of the ball taking into account it's diameter.

Some threads ago someone (do not remember who) asked for billiard physics. I send him a URL with some mathematics about this theme. Perhaps it can help you.
Here is the thread.

Oankali.
 
Last edited by a moderator:
One quick and dirty was would be to create four separate collision masks, one for each of the following segments of the ball: Top, Bottom, Left and Right.

So assuming a crude ball sprite of:

oo**oo
o****o
******
******
o****o
oo**oo

Create the following 4 masks

Top
oo**oo
o****o

Bottom
o****o
oo**oo

Left
o*
**
**
o*

Right
*o
**
**
*o

Four separate collision checks can now be performed to find out which sides (yes I know a ball doesn't actually have sides as such) are colliding.

It all depends what level of accuracy you are after but this would work for a breakout of Puzzle Bubble type game.
 
Well, since it's not 1 AM anymore, I've had some time to think about how I did it before:

First, change the Y position. Next, check to see if there is a collision on either the top or bottom edge of the object. If there is, flag that there is a collision on the Y plane. If not, don't. Finally, undo the move that you did in the beginning.
Then check the next object's Y plane, and the next, and the next, etc etc.

After that, do the same, but on the X plane.

At this point, the game knows whether or not the movement it was about to do for each object will cause a collision.

For each object, check its collision flags and react accordingly. Then update the position of the object on both x and y planes.

Now, the reason I undo the movements of the objects after I check is so that there's some degree of uniformity, if that's even a word. Basically, this is to eliminate any chance of the collision being handled differently depending on the object's position in the array. It's a way of checking all of the collisions at the same time.

Now, that makes sense in theory, I'll have to put it to test. I check each plane seperately so I know EXACTLY which movement caused the collision. if there was no collision, and then a movement on the x axis caused a collision, then I know the top and bottom aren't causing thatcollision. If there was no collision, and then a movement on the y axis caused a collision, then I know the left and right aren't causing that collision.

Now, you know the Incredible Machine, right? When an object is selected, it draws that box around it? I implemented that too, and the code stores the locations of each edge of the object into an array. I decided to also use that array for collisions. That's why I'm doing it so funky.

NOW the only thing I need to think about is... you know when you have a ball, and it falls onto a floor, right? Now, if it falls onto the CORNER of the floor, it makes the ball bounce diagonally. I need to figure that out, and I think I know exactly how to do it.

Thanks for help, I'll let you know if this works.
 
Hi Drag,

i don't know much about the incredible machine, so I don't know if your walls move or not, but if they DON'T, you can greatly simplify the collision detection.

For example, if the walls DON'T move:

After the ball moves (you know dx and dy - change is x and y) there is a collision, so if dy was positive (ball moving down) you know that the collision can't have been on top of the ball, and if dx was positive, you know the collision can't have been on the left of the ball. All you need to do now is detect whether it was vertical, horizontal or both.

An easy way to do this would be to first move the ball in the y direction, check for a collision, then move the ball in the x direction and check for a collision.

If your walls are only exactly vertical or horizontal, you only need to check two points for collisions depending on the dx and dy of the movement. Of course, a ball being round, there is ALWAYS only 1 point that sticks out furthest (the apex of the curve) so all you need to do is check for collision between this point and the walls.

As Oankali said, you just step from the centre of the ball by the radius to get the point.

So if dx is 2 and dy is -3 (moving up to the right) you need to check for collisions at:
bc_ = ball center (x or y), r = radius
(bcx+r, bcy) and (bcx,bcy-r)

EDIT:
A simple way of bouncing the ball off the walls is -
if the ball hits a wall vertically (i.e. floor or ceiling) simply reverse dy (the direction of vertical travel)
if the ball hits a wall horizontally (i.e. walls) simply reverse dx

Therefore, if the ball falls in a corner, you don't need any special case calculations because both of these will occur, and your ball will bounce out diagonally (as long as it came in diagonally).

Of course to do it properly you would model the springiness of the ball, and how much elastic potential energy is imparted on the ball with each bounce, so you can do the proper physics, taking gravity and other external forces into account.

Hope it helps,
Pea
 
Last edited by a moderator:
You could also detect it with some simple math -- ie: A ball is a circle (which could also be used around players etc invisibly, so they dont' feal like boxes.), so you could check the distance from circle center to the object edge (and you know the diamter of the circle) to know 'if' theres been an impact; further, you know the direction of travel (since you're moving the circle) so can determine what to do. (Course, 'distance to object' can be tough depending what you're doing..)

jeff
 
Thanks for the help everyone.

I did eventually get it working the way I described in my post.

It works well enough, so I'm just going to use it. Now, this box region check isn't good for inclines, but that's not a problem, I've already mapped out a way to get that working, and it's a similar method to how I did it in Roboll. (using a slope value for both more detail and to get the ball rolling down the slope)

Everything is coming along very nicely, and I would very much like to release a demo of this game at one point, although it'll be very limited as it's not even a quarter done yet...

Getting to play with it is funner than just looking at it. :)
 
Back
Top