Reputation: 391
I am trying to set up a gravity system in a project I am working in. But for some reason it is not being applied. Is there something I am missing or doing wrong?
For context, I am using Box2D 3.0.0 and SDL2 I have the important code below. The variable _props is in charge of drawing the world.
Creating the world:
entitymanager::entitymanager() {
auto worldDef = b2DefaultWorldDef();
worldDef.gravity = {0.0f, -10.0f};
_world = b2CreateWorld(&worldDef);
}
Create a body:
auto bodyDef = b2DefaultBodyDef();
bodyDef.position = {.0f, .0f};
bodyDef.type = b2_dynamicBody;
const auto body = b2CreateBody(_world, &bodyDef);
b2Polygon shape = b2MakeBox(
(width - margin.left - margin.right) * .5f,
(height - margin.top - margin.bottom) * .5f
);
b2ShapeDef shapeDef = b2DefaultShapeDef();
shapeDef.density = p.value("density", 1.f);
shapeDef.friction = 0.3f;
b2CreatePolygonShape(body, &shapeDef, &shape);
On every game loop I do this:
void entitymanager::update(float_t delta) {
b2World_Step(_world, delta, 4);
for (const auto &entity : _entities) {
entity->update();
}
}
Where entity::update is:
const auto position = b2Body_GetPosition(_props.body);
_props.position.set(
static_cast<int32_t>(std::round(position.x)),
static_cast<int32_t>(std::round(position.y))
);
_props.angle = b2Rot_GetAngle(b2Body_GetRotation(_props.body));
Upvotes: -5
Views: 141
Reputation: 159
This is a classic mistake regarding rounding and casting. Rounding a position in space or casting a fraction to an integer, results in the integer discarding any fractional information. What happens is that your delta is too small for the position to significantly update to a new integer position. So, when you round it, it will round to the nearest integer. In this case back to its original position. Try to avoid rounding when it comes to position. You could also increase the gravity to see when it begins to move.
Edit: The solution has come to light, though rounding a position can have this effect as well.
Upvotes: 3