1
\$\begingroup\$

I'm making a 2D platformer game and using the separating axis theorem for collision detection, but I want the player to be able to walk along the ground and slide on walls and other stuff and I can't find anything online.

For moving I have:

//in my Entity class, where each entity has a collider
//and is added to the world on creation
public void Move(Vector amount)
{
    Pos += amount;
    if(world.isCollidingWithAnything(this))
    {
        Pos-=amount;
    }
}

If I move into a collision it stops all movement that frame, even if the movement is parallel to the obstacle. How do I make it to where they can walk along the ground without splitting the x and y movement?

\$\endgroup\$

2 Answers 2

1
\$\begingroup\$

Separating axis doesn't mean you have to split along x and y. You can pick other bases.

Make the axes the normal perpendicular to the wall and the tangent along the wall.

Then you can set the speed and movement along the normal to 0 and keep the speed and motion along the tangent as is.

\$\endgroup\$
1
\$\begingroup\$

Is a top down or a platformer 2D game? Assuming it's a top down, what you want to do is to compare the movement amount vector to the normal of the wall that you've hit. Your two most extreme cases will be these:

1) Your movement vector and wall normal are parallel - you've hit the wall head on and you want to stop completely.

2) Your movement vector and wall normal are perpendicular - you're moving prefectly along the side of the wall and want to keep the same speed.

Anything between these two cases you want to interpolate - meaning if you've hit the wall, for example, at a 45 degree angle you most likely you want to slide along the wall but at 50% of your speed.

Here's how you can achieve this using a Cross Product and Vector Projection.

First you want to find your wall tangent (or "vector along the wall"), again assuming it's a top down game:

wallTangent = Vector.Cross(wallNormal, Vector.up);

Great, you have base vector for moving along the wall. Now you need to achieve the interpolation that I've mentioned between hitting the wall completely and perfectly sliding along, depending on the angle that the character hits the wall. For this you can use Vector Projection.

movementAlongWallAmount = Vector.Project(movementAmount, wallTangent)

Note: this code does not handle "pushing out of collision", I'm assuming you already have this working on a different system.

\$\endgroup\$

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .