2d sliding collision detection

Started by
5 comments, last by BeerNutts 11 years, 4 months ago
So I've started working on an extremely simple 2d tiled sidescrolling engine, using pygame (i know, but pretty much only for rendering + input). The problem is that the way that I've set up collision detection causes an object to stop moving in all directions when it hits another object. Here's the code for collision detection:
[source lang="python"]


def checkcollision(ob1, ob2):
if(ob1.x+ob1.w > ob2.x and
ob1.x < ob2.x+ob2.w):
if(ob1.y+ob1.h > ob2.y and
ob1.y < ob2.y+ob2.h):
return True
else:
return False
else:
return False

def collision():
for atile in mainarea.tiles:
if(checkcollision(player,atile)):
player.move(-player.vx, -player.vy)
player.vx = 0
player.vy = 0
[/source]
My question is, how can I implement collision detection that will only stop movement along one axis, but allow the other axis to keep moving (cause 'sliding' along walls instead of sticking)?

I apoligize if I'm asking in the wrong place, but it seems like a rather general question, and I didn't want to put this under physics, as I do not think it qualifies.
Advertisement
You could check each direction and set a min/max velocity in that direction in the event of a collision.
In the event of a collision on the right side of the object, the velocity along the X axis would be set to zero if it was above zero (this would allow negative X values because they would move you away from the object with which you are colliding).

Inspiration from my tea:

"Never wish life were easier. Wish that you were better" -Jim Rohn

soundcloud.com/herwrathmustbedragons

What always works good is if both objects have a velocity

For example your vehicle: 100 speed units

Your Enemie 25 speed units

Your new Velocity := V1 - V2 = 75
Enemy Velocity = V2 - V1 = -25

Edit: The velocity of course should be a vector so you can move in each axis direction)

Just for example..

So you move slower but at the same time you push the enemy back and no one stuck (and it works with much more objects)

Regards

from time to time i find time

Alright, i think i get what you're saying. So i don't need to check top, left, bottom, right, but rather x and y collision? Thanks for the help.
Paul Nettle's reference here explains a theory of how to do this. While the result is focused on 3D and ellipsoids, it does lead up to that by describing the method as it applies to 2D and circles. The section on sliding applies to things other than spheres either way and demonstrates how to get the sliding vector from the direction vector and obstacle plane.
just use box2d
The method I always tout is to move 1st along the x-axis, then check collisions; if it hit something, move back and stop x-velocity. Then move in Y-direction; if it hit something, move back and stop y-velocity.

That should handle when you hit the wall during a jump, but you continue to rise and fall, and it will also handle when you jump and hit your head on the ceiling, but your character continues to move along the x-axis.

The obvious downside is you're doing 2 checks per update, but unless it's a complex game with many many collisions to check, it's going to be fine. If you do have a lot of objects, I'd recommend looking into spatial hashing, but this isn't needed until you see performance issues.

Good Luck!

My Gamedev Journal: 2D Game Making, the Easy Way

---(Old Blog, still has good info): 2dGameMaking
-----
"No one ever posts on that message board; it's too crowded." - Yoga Berra (sorta)

This topic is closed to new replies.

Advertisement