Sign in to follow this  

2d sliding collision detection

Recommended Posts

Med_Ved12    103
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
return False
return False

def collision():
for atile in mainarea.tiles:
player.move(-player.vx, -player.vy)
player.vx = 0
player.vy = 0
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.

Share this post

Link to post
Share on other sites
InferiorOlive    1065
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).

Share this post

Link to post
Share on other sites
~Helgon    361
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 Edited by ~Helgon

Share this post

Link to post
Share on other sites
freakchild    572
Paul Nettle's reference [url=""]here[/url] 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. Edited by freakchild

Share this post

Link to post
Share on other sites
BeerNutts    4400
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!

Share this post

Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this