Collision Resolution Help

Whether you're a newbie or an experienced programmer, any questions, help, or just talk of any language will be welcomed here.

Moderator: Coders of Rage

Post Reply
User avatar
lotios611
Chaos Rift Regular
Chaos Rift Regular
Posts: 160
Joined: Sun Jun 14, 2009 12:05 pm
Current Project: Game engine for the PC, PSP, and maybe more.
Favorite Gaming Platforms: Gameboy Micro
Programming Language of Choice: C++

Collision Resolution Help

Post by lotios611 »

I'm trying to implement the method of collision resolution described here and I can't get it to work.

Here's the code:

Code: Select all


bool IsCollision(Rectangle rectangleA, Rectangle rectangleB)
{
	if (rectangleA.x < rectangleB.x + rectangleB.w &&
	    rectangleA.x + rectangleA.w > rectangleB.x &&
	    rectangleA.y < rectangleB.y + rectangleB.h &&
	    rectangleA.y + rectangleA.h > rectangleB.y)
	{
		return true;
	}
	return false;
}

...

if (IsCollision(rectangleA, rectangleB))
        {
            Rectangle overlap;
            overlap.h = rectangleB.y + rectangleA.h- rectangleB.x;
            overlap.w = rectangleA.x + rectangleA.w - rectangleA.y;
            Rectangle centerPointA;
            centerPointA.x = rectangleA.x + rectangleA.w / 2;
            centerPointA.y = rectangleA.y + rectangleA.h / 2;
            Rectangle centerPointB;
            centerPointB.x = rectangleB.x + rectangleB.w / 2;
            centerPointB.y = rectangleB.y + rectangleB.h / 2;
            if (overlap.w < overlap.h)
            {
                if (centerPointA.x < centerPointB.x)
                {
                    rectangleA.x -= overlap.w;
                }
                else
                {
                    rectangleA.x += overlap.w;
                }
            }
            else
            {
                if (centerPointA.y > centerPointB.y)
                {
                    rectangleA.y -= overlap.h;
                }
                else
                {
                    rectangleA.y += overlap.h;
                }
            }
        }

"Why geeks like computers: unzip, strip, touch, finger, grep, mount, fsck, more, yes, fsck, fsck, fsck, umount, sleep." - Unknown
N64vSNES
Chaos Rift Devotee
Chaos Rift Devotee
Posts: 632
Joined: Thu Aug 12, 2010 11:25 am

Re: Collision Resolution Help

Post by N64vSNES »

Oh dear...

First of all, you might want change your detection code slightly, before you get onto resolution:

Code: Select all

bool IsCollision(Rectangle rectangleA, Rectangle rectangleB)
{
   if (rectangleA.x < rectangleB.x + rectangleB.w && // Should be: Ax + Bw > Bx
       rectangleA.x + rectangleA.w > rectangleB.x && // Should be: Ax - Bw < Bx
       rectangleA.y < rectangleB.y + rectangleB.h &&  // Should be: Ay + Bh > By
       rectangleA.y + rectangleA.h > rectangleB.y)       // Should be: Ay - Bh < By
   {
      return true;
   }
   return false;
}
You're supposed to be adding and subtracting the alternate object's dimensions from the position of the object you're checking, thus if all statements are correct there must be a collision.

Like so:

Code: Select all

if ( A->x + B->w > B->x && A->x - B->w < B->x 
     && A->y + B->h > B->y && A->y - B->h < B->y )
{
    // Hooray for collision!
}
For the resolution:

Code: Select all

Rectangle overlap;

overlap.h = rectangleB.y + rectangleA.h - rectangleB.x;
overlap.w = rectangleA.x + rectangleA.w - rectangleA.y;
..Wtf?
To calculate how much A is overlapping B, you take Ax, add Aw, and then subtract Ay? :nono:

First calculate the distance between the objects, then I'm sure you'll find it fairly easy to get the overlap of the two ;)
Think of the distance as a line between the two objects, the value of this line itself can be used to represent the overlap.

If the distance between the two on the X-axis is 40, and the width of both A and B are 44, they are overlapping each other by 4-units along this axis. Apply this to the Y-axis and poof, you've got your overlaps.

So for the distance between A and B you would do:
Distx = Ax - Bx
Disty = Ay - By

Code: Select all

Rectangle centerPointA;
centerPointA.x = rectangleA.x + rectangleA.w / 2;
centerPointA.y = rectangleA.y + rectangleA.h / 2;

Rectangle centerPointB;
centerPointB.x = rectangleB.x + rectangleB.w / 2;
centerPointB.y = rectangleB.y + rectangleB.h / 2;
This section is okay, but I would advise you to handle the objects from the center in the first place, so this wouldn't be necessary.

Have a read through this:
viewtopic.php?f=13&t=5767&p=69710&hilit ... ial#p69710

Let me know if you find any more problems.
User avatar
lotios611
Chaos Rift Regular
Chaos Rift Regular
Posts: 160
Joined: Sun Jun 14, 2009 12:05 pm
Current Project: Game engine for the PC, PSP, and maybe more.
Favorite Gaming Platforms: Gameboy Micro
Programming Language of Choice: C++

Re: Collision Resolution Help

Post by lotios611 »

Thanks for your help, I got it working by copying your code in the other tutorial. I understand how it's done now.
"Why geeks like computers: unzip, strip, touch, finger, grep, mount, fsck, more, yes, fsck, fsck, fsck, umount, sleep." - Unknown
Post Reply