Custom Collision Checking problem
#1
Posted 02 January 2012 - 11:08 PM
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.
Thanks for your help in advance.
#2
Posted 03 January 2012 - 12:05 AM
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.
#3
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.
#4
Posted 03 January 2012 - 01:42 AM
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
#5
Posted 03 January 2012 - 04:40 AM
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.
#6
Posted 03 January 2012 - 04:59 AM
Edited by Dragon47, 03 January 2012 - 04:59 AM.
#7
Posted 03 January 2012 - 09:30 AM
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.
#8
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.
#9
Posted 03 January 2012 - 08:45 PM
Your illustrations have boxes. bbox_min_x is the leftmost (smallest) x coordinate in the collision mask. Similar for the rest.Ahh. That's interesting. But in the [p]s[e]udocode, what does bbox_min mean?
#10
Posted 03 January 2012 - 09:06 PM
Your illustrations have boxes. bbox_min_x is the leftmost (smallest) x coordinate in the collision mask. Similar for the rest.
Ahh. That's interesting. But in the [p]s[e]udocode, what does bbox_min mean?
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 user(s) are reading this topic
0 members, 0 guests, 0 anonymous users



This topic is locked







