walking on a slope

95 views
Skip to first unread message

dsza...@gmail.com

unread,
Dec 21, 2014, 5:57:14 PM12/21/14
to mel...@googlegroups.com
Hello,

While running the "stock" platformer example I've noticed the following glitches when the player is on a slope:
- it moves much faster upwards than downwards
- it cannot stop on the slope: if it moved upwards, the entity will slowly slide down. if it moved downwards, it will rush down without stopping.

How can I fix these issues?

Jay Oster

unread,
Dec 21, 2014, 7:33:45 PM12/21/14
to mel...@googlegroups.com, dsza...@gmail.com
I guess you meant "much faster downwards than upwards" in your first point. :)

The reason behind this behavior is caused by the way the collision detection (SAT) applies the collision response to a moving entity. When a shape collides with a slope, SAT determines which axis has the shortest depth. For slopes at a 45 degree angle or steeper, the shortest axis is almost always going to be the X-axis. So that when the collision response is applied, it pushes the entity to the left or right. On the next frame, gravity will pull the entity back down into the slope for another collide, and the process repeats. This causes the entity to slide down the slope.

This behavior also explains the slow movement uphill; When the collision response is applied, your entity is pushed AGAINST its movement direction, but its velocity will be higher than gravity (which is less than 1px per frame) so it still makes upward progress. Going downhill is not impeded by collisions, but instead propelled, because the entity will be pushed in the same direction as it is moving.

To change the slope behavior, you can use the standard collision handlers, and adjust the response object. The easiest way is to set the overlapV.x axis to 0 (do not adjust left or right), and set the y axis to the absolute value of the overlap (always adjust upward). You'll want to give your slope shapes a custom type to identify them for the response adjustment.

onCollision : function (response, other) {
    switch (other.body.collisionType) {
        case me.collision.types.WORLD_SHAPE:
            // Custom collision response for slopes
            if (other.type === "slope") {
                // Always adjust the collision response upward
                response.overlapV.y = Math.abs(response.overlap);
                response.overlapV.x = 0;
                
                // Respond to the slope (it is solid)
                return true;
            }

            break;
    }
}


I tested this on the platformer, and it cancels all acceleration from the slope.

Jay Oster

unread,
Dec 21, 2014, 7:39:52 PM12/21/14
to mel...@googlegroups.com, dsza...@gmail.com
Minor correction to my explanation of the SAT axis depth; SAT uses the edge normal to calculate the shortest depth. And the shortest depth is always perpendicular to the slope itself. Entities doesn't get adjusted exactly left/right along the X axis, but instead they get adjusted perpendicular to (away from; up and to the side of) the slope. The code above attempts to counteract the slope adjustment so there is no movement along the X axis.

dsza...@gmail.com

unread,
Dec 23, 2014, 8:14:36 AM12/23/14
to mel...@googlegroups.com, dsza...@gmail.com
Thanks for your answer, I'll apply your fix.
Reply all
Reply to author
Forward
0 new messages