I'm working on a 2D tile-based platformer that supports 45-degree slope tiles.
There are several questions on the topic, but none seem to cover this precise problem that I have. This excellent article covers almost everything I'd want to know. I'll copy the salient bits:
- Make sure that you step X position before Y position.
- During collision detection, the slope only counts as a collision if its closest edge is the taller (smaller y coordinate) one. This will prevent characters from “popping” through the slope from the opposite side. [...]
- A full obstacle tile adjacent to the slope the character is currently on should not be considered for collision if it connects to the slope, that is, if the character (that is, his bottom-center pixel) is on a {0, *} slope, ignore left tile, and, if on a {*, 0} slope, ignore the right tile. You may have to do this for more tiles if your character is wider than two tiles – you might simply skip checking on the entire row if the player is moving towards the upper side of slope. The reason for this is to prevent the character from getting stuck at those tiles (highlighted yellow above) while still climbing the slope, as his foot will still be below the “surface level” by the time he comes into contact with the otherwise solid tile.
So if the character is going uphill, we essentially allow him to penetrate the slope after we've stepped the x coordinate, and then rectify that when we step the y coordinate. Let's assume we're using one contact point for the characters feet:
However, when the character reaches the top of the slope, at some point he'll step into the next tile:
As per the last bullet point above, we allowed him to move into the solid tile because it's ajacent to the slope. But now we're inside the floor, which needs to be fixed somehow.
What logic is needed to correctly resolve this situation? Simply saying "if we penetrate a solid tile, move up until we're out of it" doesn't always work, because there might be another solid tile on top of it, and we don't want the player to be teleported all the way to the top.
Can this be done without any communication between the x update and the y update, or do we need to keep some state like "I was on a slope at the start of this frame"? What is the most robust and elegant way to handle this?