Custom Collision Checking problem

9 replies to this topic

#1 Pixelated_Pope

Pixelated_Pope

GMC Member

• GMC Member
• 128 posts

Posted 02 January 2012 - 11:08 PM

Hi all.

I'm using the "custom" (i.e. not using built in collision functions) collision method Mike Daily described in his blog. LINK (Scroll down to contra dude.)

It's pretty simple box collision, but I need to know whether my character is colliding with the side of the other rectangle, or if it is colliding primarily with the top... I'm not even sure if I can do anything like that when I am using this method of collision, but if anybody has any ideas on how I could tell if my character is landing on top of the box or running into the side (left or right) that would be awesome.

For those who are curious, the reason I'm not using the built in collision, is that each object requires multiple areas of collision. One object might have 4 different "hit" zones, and 1 area that acts as a platform. The character has a box that acts as collision with the world/vulnerable area from other attacks, and 1 or more areas that act as an attack based on the current attack animation.

Collision is by far my weakest aspect of game programming... so any articles that you might know of that could help with custom building collision, that would be awesome. I'm open to changing my collision method completely if some plausible alternatives are proposed.

Oh, and I guess it might help to understand exactly what I am building. I am remaking the "beat the car up" mini game from Street Fighter II (SNES). And I'm trying to figure out whether Ken is running into the side of the car, or jumping onto the hood.

My GMK can be made available if necessary.

• 0

#2 Dragon47

Dragon47

GMC Member

• GMC Member
• 147 posts
• Version:GM8

Posted 03 January 2012 - 12:05 AM

Since it's a box collision I would simply check with x < other x etc

Where other is the variable of the box youre colliding with (with origin 0,0):

if (x < other.x)
collision on left side

if (x > other.x + other.width)
collision on right side

if (y < other.y)
collision on top

if (y > other.y + other.height)
collision on bottom

Edited by Dragon47, 03 January 2012 - 12:05 AM.

• 0

#3 Pixelated_Pope

Pixelated_Pope

GMC Member

• GMC Member
• 128 posts

Posted 03 January 2012 - 12:56 AM

Since it's a box collision I would simply check with x < other x etc

Where other is the variable of the box youre colliding with (with origin 0,0):

if (x < other.x)
collision on left side

if (x > other.x + other.width)
collision on right side

if (y < other.y)
collision on top

if (y > other.y + other.height)
collision on bottom

That doesn't really work...

Maybe a screenshot will help...

(Distance refers to the horizontal distance between the two origins. Min Width is the width of the two collision boxes added together... if distance < width, then there is a collision... IF the same is true for the y distance and height).
Ken is standing on the floor there. To get a collision event to fire at all, then x would be less than other.x and y would be less than other.y.

So if I jump on top of the car, x is less than other x, however, I am colliding with the top.

I think a more complex solution is in order... or maybe you could be more explicit.

Edited by Pixelated_Pope, 03 January 2012 - 12:59 AM.

• 0

#4 Dragon47

Dragon47

GMC Member

• GMC Member
• 147 posts
• Version:GM8

Posted 03 January 2012 - 01:42 AM

I see, the xy origin is in the center, then it would be something like this:

if (x+width/2 < other.x-other.width/2)
collision on left side

if (x-width/2 > other.x + other.width/2)
collision on right side

if (y+height/2 < other.y-other.height/2)
collision on top

if (y-height/2 > other.y + other.height/2)
collision on bottom
• 0

#5 Pixelated_Pope

Pixelated_Pope

GMC Member

• GMC Member
• 128 posts

Posted 03 January 2012 - 04:40 AM

Okay... I'm still having trouble understanding.

So the first thing I need to check for is that there IS a collision at all.
```//collision[0] = hit box center X;
//collision[1] = hit box center Y;
//collision[2] = hit box Width/2;
//collision[3] = hit box Height/2;

var xdistance,ydistance;
xdistance = collision[2]+obj_car.collision[2];
ydistance = collision[3]+obj_car.collision[3];

if(xdistance >= abs(collision[0]-obj_car.collision[0])  &&  ydistance >= abs(collision[1]-obj_car.collision[1]))
{
//We have collision!
}
```

So, once I've determined that there is, in fact, a collision I need to figure out whether Ken came down on top of the car, or whether he's running into the side of the car. As an added level of complexity, if Ken is jumping towards the car, as he is jumping up, he doesn't move left or right until his collision box is above the car collision box.

I just don't see how your code snippets could be used to determine whether he is coming down from above, or moving in from the side... I'm sure it's my problem, and not your code... but I'm just not getting it.
• 0

#6 Dragon47

Dragon47

GMC Member

• GMC Member
• 147 posts
• Version:GM8

Posted 03 January 2012 - 04:59 AM

My code snippets should be used right after a collision. If its the kind of collision that checks with a "if place is free (next position)" kind of expression my snippets should be executed if the place is not free. If its the kind of collision that moves you back to your previous position if theres a collision, my code snippets should be executed after moving to the previous position.

Edited by Dragon47, 03 January 2012 - 04:59 AM.

• 0

#7 Gamer3D

Gamer3D

Human* me = this;

• GMC Member
• 1589 posts
• Version:GM8.1

Posted 03 January 2012 - 09:30 AM

A common solution is to find the shortest vector to use to push the character out. (check the amount of interpenetration in the vertical and horizontal directions). If the shortest such vector is vertical, you're either above or below. If it is horizontal, you're to the side.

So, in psuedocode:
if (player.bbox_max_x - box.bbox_min_x < box.bbox_max_y - player.bbox_min_y) || (box.bbox_max_x - player.bbox_min_x < box.bbox_max_y - player.bbox_min_y)
// You're to one of the sides.
• 0

#8 Pixelated_Pope

Pixelated_Pope

GMC Member

• GMC Member
• 128 posts

Posted 03 January 2012 - 06:47 PM

A common solution is to find the shortest vector to use to push the character out. (check the amount of interpenetration in the vertical and horizontal directions). If the shortest such vector is vertical, you're either above or below. If it is horizontal, you're to the side.

So, in psuedocode:
if (player.bbox_max_x - box.bbox_min_x < box.bbox_max_y - player.bbox_min_y) || (box.bbox_max_x - player.bbox_min_x < box.bbox_max_y - player.bbox_min_y)
// You're to one of the sides.

Ahh. That's interesting. But in the sudocode, what does bbox_min mean? Regardless, I think I understand the concept and will see if it works for me. Thanks to both of you for trying to help.
• 0

#9 Gamer3D

Gamer3D

Human* me = this;

• GMC Member
• 1589 posts
• Version:GM8.1

Posted 03 January 2012 - 08:45 PM

Ahh. That's interesting. But in the [p]s[e]udocode, what does bbox_min mean?

Your illustrations have boxes. bbox_min_x is the leftmost (smallest) x coordinate in the collision mask. Similar for the rest.
• 0

#10 Pixelated_Pope

Pixelated_Pope

GMC Member

• GMC Member
• 128 posts

Posted 03 January 2012 - 09:06 PM

Ahh. That's interesting. But in the [p]s[e]udocode, what does bbox_min mean?

Your illustrations have boxes. bbox_min_x is the leftmost (smallest) x coordinate in the collision mask. Similar for the rest.

That's what I thought. I'll try to implement it after work today and then report back on my progress. Thanks again, all.

Edited by Pixelated_Pope, 03 January 2012 - 09:06 PM.

• 0

0 user(s) are reading this topic

0 members, 0 guests, 0 anonymous users