I want to share a solution to a major problem I ran into while developing a platformer game.
This week I decided to try my hand at making a platformer in a tiled world, and ran into a BIG issue: ghost edges. Long story short, there is a fundamental flaw in Box2D that sometimes can abruptly stop a polygon (e.g. an avatar) sliding on smooth surfaces (e.g. ground) made of several tiles. This is so bad, it’s basically a game killer. It’s a well known issue and you can read more about it here:
http://www.box2d.org/forum/viewtopic.php?f=8&t=3292&start=0
http://box2d.org/forum/viewtopic.php?f=3&t=3048&start=0
http://box2d.org/manual.html#_Toc258082970
None of the suggested solutions worked for me: cutoff corners from the polygons (still gets stuck), use edge chains (don’t have them in Corona), change polygon into circle shape (my avatar is not circular and its collisions look really off with the circle shape).
So what finally did work was collision event.contact filtering. The idea is to test if the collision is about to happen between the corner of the avatar and the corner of the adjacent tile below, and if yes then remove the collision:
function avatar:preCollision(event)
local bottomLeftCornerGap = math.abs(self.view.x - 0.5 * self.view.width - (event.other.x + 0.5 * event.other.width))
local bottomRightCornerGap = math.abs(self.view.x + 0.5 * self.view.width - (event.other.x - 0.5 * event.other.width))
if bottomLeftCornerGap < 0.2 * self.view.width then
event.contact.isEnabled = false
end
if bottomRightCornerGap < 0.2 * self.view.width then
event.contact.isEnabled = false
end
end