Categories: MSDN / DotNet / Java / Scripts / Linux / PHP Ask - La ask - La Answer

Collision Detection

I'm writing a "simple" program that creates boxes or rectangles in a bounded environment. The idea is for them to bounce off of the walls of the environment and each other. I've been toying with some collision detection which only seems to work some of the time. As you can see, i'm getting if a box was hit, and if so what side the box was hit on. Maybe you can find the mistake?

for(currentBox = firstBox; currentBox.nextBox != null; currentBox = currentBox.nextBox)
{
for(currentCheckBox = firstBox; currentCheckBox.nextBox != null; currentCheckBox = currentCheckBox.nextBox)
{
if (currentBox != currentCheckBox)
{
if(currentBox.getY() == currentCheckBox.getY() + currentCheckBox.getHeight() &&
( (currentBox.getX() >= currentCheckBox.getX() &&
currentBox.getX() <= currentCheckBox.getX() + currentCheckBox.getWidth()) ||
(currentCheckBox.getX() >= currentBox.getX() &&
currentCheckBox.getX() <= currentBox.getX() + currentBox.getWidth()) ) )
currentBox.setCollision(north);

if(currentBox.getY() + currentBox.getHeight() == currentCheckBox.getY() &&
( (currentBox.getX() >= currentCheckBox.getX() &&
currentBox.getX() <= currentCheckBox.getX() + currentCheckBox.getWidth()) ||
(currentCheckBox.getX() >= currentBox.getX() &&
currentCheckBox.getX() <= currentBox.getX() + currentBox.getWidth()) ) )
currentBox.setCollision(south);

if(currentBox.getX() == currentCheckBox.getX() + currentCheckBox.getWidth() &&
( (currentBox.getY() >= currentCheckBox.getY() &&
currentBox.getY() <= currentCheckBox.getY() + currentCheckBox.getHeight()) ||
(currentCheckBox.getY() >= currentBox.getY() &&
currentCheckBox.getY() <= currentBox.getY() + currentBox.getHeight()) ) )
currentBox.setCollision(west);

if(currentBox.getX() + currentBox.getWidth() == currentCheckBox.getX() &&
( (currentBox.getY() >= currentCheckBox.getY() &&
currentBox.getY() <= currentCheckBox.getY() + currentCheckBox.getHeight()) ||
(currentCheckBox.getY() >= currentBox.getY() &&
currentCheckBox.getY() <= currentBox.getY() + currentBox.getHeight()) ) )
currentBox.setCollision(east);
}
}

if(currentBox.getX() <= 1)
currentBox.setCollision(west);
if(currentBox.getX() + currentBox.getWidth() >= maximumX - 1)
currentBox.setCollision(east);
if(currentBox.getY() <= 1)
currentBox.setCollision(north);
if(currentBox.getY() + currentBox.getHeight() >= maximumY - 1)
currentBox.setCollision(south);
}

Also, I'm currently drawing and erasing the boxes directly to the graphics buffer. I added the update method so that it wouldn't just erase everything and be super skippy, but it still isn't as nice as I would like it. I tried drawing everything to a seperate buffer, drawing that on an image, and then displaying the image, but it was really slow. Any suggestions here?
[3444 byte] By [Timothy] at [2007-11-11 7:55:44]
# 1 Re: Collision Detection
You may want to try using java.awt.Rectable. It has a method called intersects(Rectangle) that might work for you.
Laszlo at 2007-11-11 22:37:02 >
# 2 Re: Collision Detection
You may want to try using java.awt.Rectable. It has a method called intersects(Rectangle) that might work for you.
Do you mean Rectangle? It also has a method contains(Rectangle) which would work nicely for keeping within the window.
Rectangle bounds = new Rectangle(0, 0, getWidth(), getHeight());
Then you can just use if bounds.contains(yourRect).
destin at 2007-11-11 22:37:56 >
# 3 Re: Collision Detection
I typed Rectable? :eek: DUH. Thanks, Destin. Yes, Rectangle. :D
Laszlo at 2007-11-11 22:38:55 >
# 4 Re: Collision Detection
I typed Rectable? :eek:
lol... I thought it was some weird class I've never heard of. Thank god for google... keeping me sane.
destin at 2007-11-11 22:40:05 >
# 5 Re: Collision Detection
Would using Rectangle give me what side of the square the collision occured on? I need that information because I use it to determine which way the boxes should "bounce". I thought about using it before, but I just wasn't sure.

I also can't seem to grasp why my collision detection doesn't work, but I guess if I can't figure it out it would be even harder for someone else to.

Thanks again.
Timothy at 2007-11-11 22:41:04 >
# 6 Re: Collision Detection
You're absolutely right. intersects() will not give you anything but a boolean. However, intersection will give you a Rectangle (with an x,y,width, and height) of the rectangle where they intersect. It's a simple comparison to figure out which of your sides are in contact.

But then it's fairly simple math the way you're doing it now. I just thought I'd offer it, in case it makes your code any simpler.

Interesting design. I would have done it a little differently, but that's not the issue. I'd consider the == comparisons you're doing. If you have boxes moving toward each other, right before they collide "north" their Y (and Y+height) might be exactly one different. Then as one moves up and one moves down, they collide, but the == doesn't see it, because they're not equal, they're one-past-collision. Try <= and >= in stead of ==, to see whether the went past each others' collision point.

Or a better design mgiht be to have each box be intelligent enough to check to see whether it's about to run into another box, before actually doing the move. If it is, then don't move and perform whatever collision routine it needs to.
Laszlo at 2007-11-11 22:42:08 >
# 7 Re: Collision Detection
Will do. Thanks.
Timothy at 2007-11-11 22:43:06 >
# 8 Re: Collision Detection
you check all boxes everytime for collision.
its not required ; when you move a box, check only for it.

if you mix position of boxes with movement ( direction and speed ) ; collision detection may not need handle directions in that way.

simple way :
( dx = 1 AND collision occured => dx = -1 )
mr1yh1 at 2007-11-11 22:44:10 >