0
votes

I have this very odd problem with Box2D (under iOS). I have a body that is resting on the bottom of the screen. If I set the body from b2_dynamicBody to b2_staticBody using body->SetType(b2_staticBody), then later set it back to b2_dynamicBody, it falls through the bottom of the screen for a quick moment (several frames as I can see it moving down) before being pushed back up through the floor and coming to a rest correctly.

This behavior seems to only happen on the bottom of the screen. Doing the same thing with other bodies sitting on each other does not product this behavior.

I am defining the screen edges as follows (screenRect as already been adjust to world space):

b2BodyDef groundBodyDef;
groundBodyDef.position.Set(0,0);
b2Body* groundBody = globalWorld->CreateBody(&groundBodyDef);
b2PolygonShape groundBox;
b2FixtureDef boxShapeDef;
boxShapeDef.shape = &groundBox;
groundBox.SetAsEdge(b2Vec2(screenRect.p1.x,screenRect.p1.y), b2Vec2(screenRect.p2.x,       screenRect.p1.y));
groundBody->CreateFixture(&boxShapeDef);
groundBox.SetAsEdge(b2Vec2(screenRect.p1.x,screenRect.p1.y), b2Vec2(screenRect.p1.x, screenRect.p2.y));
groundBody->CreateFixture(&boxShapeDef);
groundBox.SetAsEdge(b2Vec2(screenRect.p1.x,screenRect.p2.y), b2Vec2(screenRect.p2.x, screenRect.p2.y));
groundBody->CreateFixture(&boxShapeDef);
groundBox.SetAsEdge(b2Vec2(screenRect.p2.x,screenRect.p2.y), b2Vec2(screenRect.p2.x,       screenRect.p1.y));
groundBody->CreateFixture(&boxShapeDef);

The oddest part of this is the more I switch the body from dynamic to static, the farther and farther it falls through the floor before being pushed back up.

I have not changing anything else in the body except from dynamic to static. If I move the body and drop it back onto the floor, the start switching it from dynamic to static, it resets how much it's drop into the floor, but it build up again the more I switch.

I can't figure out why is is falling through the floor like this unless I'm creating it incorrectly. Everything else in the game works perfectly.

1

1 Answers

0
votes

I had this problem too. Here is my theory: when the object is static, it stops generating contacts with other static stuff like the ground. So, it seems that when set to dynamic again, it fails to update this contact checking.

My solution was this: since changing the position of an object correctly update these contacts, I just move the object to its current place. Unfortunately, it's detected as a zero change. So, I need to move it elsewhere, then move it again to its previous position.

b2Vec2 pos = body.getPosition();
float ang = body.getAngle();
b2Vec2 off_map(-100,-100);
body.setPositionAndAngle(off_map, 0);
body.setPositionAndAngle(pos, ang);

If you don't have an off-map area, you can try deactivating the object during the first move.