I am working on a new 2D platformer game.
I have been using Box2D for the physics.
For the level itself I used a single b2ChainShape which includes both the floor and the walls.
For my game I need to recognize when the character contact the wall and when it contacts the floor but more importantly when the character ends the contact with the floor or wall.
I could have used two separate fixtures(one for the walls and one for the floor) but according to Box2D I wouldn’t get the perfect collision detection as I would with a single shape.
By implementing b2ContactListener you can listen to when two bodies have a new contact point and when they end the contact.
To recognize if the character contacts either the wall or the floor I used GetWorldManifold on b2Contact which is provided as a parameter of BeginContact.
b2WorldManifold contains the normal of the contact surface. With the normal I can easily recognize if the contact point is with a wall or the floor.
However, on EndContact you cannot get b2WorldManifold or the data you will get is garbage.
So how can we tell when we end the contact with the floor rather than the wall?
The solution is to keep 3 counters: The total contact points, the left walls contact points and the right wall contact points.
The total contact points counter includes all the walls and the floor contact points.
When we want to know if we are in contact with the walls and not the floor(like touching the wall mid air) we simply subtract the wall contact counters from the total contacts counter.
When the EndContact method is called we reduce the total contacts counter by one and zero out the walls contact counters.
This will work if the walls are perpendicular to the floor(like a tile based game).
A more complex level might need a better solution.