c++box2d

What could cause a sudden stop in Box2D?


I'm using Box2d for a game, and I have a bug that's driving me nuts. I've simplified the situation down to a square player sliding back and forth frictionlessly on top of a floor composed of a series of square tiles, driven by the left and right keys (which apply a horizontal force). Works great, sliding back and forth across the whole floor.

Except... Every once in a while, the player will suddenly stick at the edge of one of the tiles as if it is hitting a (nonexistent) wall. Further pushes in the same direction it was traveling will fail, but as soon as I push backwards once in the opposite direction, I can push forwards past the sticking point again. The sticking point seems to be random, except for being on the edge of a tile. Happens while going left or right.

For debugging purposes, I keep the Positions/velocity values for the previous two update ticks and print them out when this stop occurs. As an example, here you see the player moving right, decelerating slightly; pos2 should be about 8.7, but it stops dead instead.

tick0:  pos= 8.4636 vel= 7.1875
tick1:  pos= 8.5816 vel= 7.0833
tick2:  pos= 8.5816 vel= 0.0000

So, as the player is 0.8 and the tiles 1.0 wide, the player is stopping just as it is about to cross onto the next tile (8.5816 + 0.8/2 = 8.9816). In fact, I get a collision message (which I ignore except noting that it happened). It only seems to happen at x.5816 (or -x.4184) while moving right, and x.4167 (or -x.5833) while moving left

I said that it's like hitting a wall, but in fact, when it hits a wall, the numbers look more like:

 tick0:  pos0= 12.4131 vel2= 8.4375
 tick1:  pos1= 12.5555 vel1= 8.5417
 tick2:  pos2= 12.5850 vel0= 0.0000

so it moves further right on the last tick, which puts it in contact with the wall.

Anyone seen anything like this? Any suggestions on how I could be causing this behavior?


Solution

  • Unfortunately, this is a known issue in Box2d... from the FAQ:

    Tile Based Environment

    Using many boxes for your terrain may not work well because box-like characters can get snagged on internal corners. A future update to Box2D should allow for smooth motion over edge chains. In general you should avoid using a rectangular character because collision tolerances will still lead to undesirable snagging.

    For more information see this post: http://box2d.org/forum/viewtopic.php?f=3&t=3048

    And from Eric Catto, creator of Box2d (Emphasis added):

    I'm working a solution for edge chains, but there is no solution for adjacent polygons. You are really better off using one or more circles for character vs environment. Most professional games using modern physics engines use smooth shapes, like capsules, for characters. Using box shapes for characters really only works well in systems that use pixel based collision with integral math (i.e. older console games).

    So basically, your body should be a smooth shape, and not a polygon so that it doesn't snag between tiles.