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 Falsedef 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.
2d sliding collision detection
Started by Med_Ved12, Dec 16 2012 10:29 PM
6 replies to this topic
Sponsor:
#2 Members - Reputation: 325
Posted 16 December 2012 - 10:43 PM
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).
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).
#3 Members - Reputation: 321
Posted 17 December 2012 - 12:43 AM
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
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, 17 December 2012 - 12:44 AM.
from time to time i find time
#5 Members - Reputation: 550
Posted 17 December 2012 - 06:06 PM
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.
Edited by freakchild, 17 December 2012 - 06:07 PM.
#7 Members - Reputation: 1566
Posted 18 December 2012 - 09:26 AM
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!
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)
---(Old Blog, still has good info): 2dGameMaking
-----
"No one ever posts on that message board; it's too crowded." - Yoga Berra (sorta)






