3
\$\begingroup\$

I'm making a space game with LibGDX and Box2D. I made a video here to illustrate the issue.

Verbal description: When objects collide, they sometimes get stuck together and are then suddenly separated by a strong force.

Both objects have identical body definitions and fixtures:

bod = new BodyDef();
bod.type       = type;
bod.allowSleep = false;

shape = new CircleShape();
shape.setRadius(values[0]);

fix = new FixtureDef();
fix.restitution = 0f;
fix.friction    = 1f;
fix.shape       = shape;
fix.density     = 1f;

worldBod = world.createBody(bod);
worldBod.setTransform(position.x, position.y, 0);
worldBod.createFixture(fix);

Why might this be happening? How can I fix it?

Update: Here is some more info.

The Player class contains a function update(float deltaTime) with the rest listed below

force.x += (directionVector.x * SPEED)*deltaTime;
force.y += (directionVector.y * SPEED)*deltaTime;


//This helps keep the object in control from preventing forces greater then 3
if(force.x >= 3){
    force.x = 3;
}if(force.x <= -3){
    force.x = -3;
}if(force.y >= 3){
    force.y = 3;
}if(force.y <= -3){
    force.y = -3;
}
//This quickly reduces the force back down to 0
force.x *= 0.5;
force.y *= 0.5;

this.getBody().applyForceToCenter(force, true); 

In the render part of the main game class I step the world with

gameWorld.step(Gdx.graphics.getDeltaTime(), 6, 6);
//although increasing or decreasing the itterations seems not to help

and Finally the hexagon's are created using the ShapeRenderer pulling the position and

sr.setProjectionMatrix(camera.combined);
sr.begin(ShapeType.Line);
sr.circle(p1.getBody().getPosition().x, p1.getBody().getPosition().y, 1);
sr.circle(barrierPole.getBody().getPosition().x, barrierPole.getBody().getPosition().y, 1);
sr.end();
\$\endgroup\$
2
\$\begingroup\$

Don't use a variable time step for physics, this will mess up the entire engine.

Box2D will attempt to apply enough force depending on the level of penetration, if the step is constantly changing then Box2D is getting different numbers each time it tries to separate fixtures.

Use an fixed timestep instead:

world.step(1f/60f, 5, 8);

Or some other variation, I sometimes do 1f/30f, depending on the performance of the high time step.

\$\endgroup\$
  • \$\begingroup\$ This didn't fix the problem, and now I use a semi-fixed timestep instead. I managed to fix the problem by accident and still have no idea what was causing it but thanks! \$\endgroup\$ – Snowdrama Mar 19 '15 at 23:17
  • \$\begingroup\$ Good to hear you got it working! Sorry my answer could not be of more help. \$\endgroup\$ – Gibbo Mar 20 '15 at 9:05
  • \$\begingroup\$ @Snowdrama Warning: If you're not using a definite/fixed time-step, you might have solved the problem for your system only. It may be possible that a different system, which runs with faster/slower time-steps, will behave differently. --- There are solid reasons why the "right" way to do physics is with fixed time-steps. \$\endgroup\$ – XenoRo Dec 7 '17 at 19:07
  • \$\begingroup\$ @XenoRo When I mentioned a semi-fixed, what I meant was I had separated physics and other updates. Physics were fixed, but other updates were not. As a side note this was 2 years ago, and as I recall the time step was only part of the problem. The main issue was something I wasn't able to spot and had to do with how I was turning the object, sometimes it would spin incredibly fast and that was the "separate forcibly" part. They would casually drift closer like I expected but at 1000 rpm and when they touched they would act strangely. I figured it out right after attaching sprites. \$\endgroup\$ – Snowdrama Dec 10 '17 at 18:17
1
\$\begingroup\$

Try to think about what happens when the objects overlap by a bit. This is the usual reason for such behaviour. Most likely the issue is in the part where collision is worked out and the force after collision applied.

\$\endgroup\$
1
\$\begingroup\$

b2Settings::b2_velocityThreshold

https://github.com/erincatto/Box2D/blob/f655c603ba9d83f07fc566d38d2654ba35739102/Box2D/Box2D/Common/b2Settings.h#L94

If something with speed below that value hits a wall, it just sticks to it instead of bouncing back.

The default value is 1.0 currently. To modify it you have to hack the define in that header file apparently.

Here is a simple Urho3D example to illustrate this point: https://github.com/cirosantilli/Urho3D-cheat/blob/7f48db5046bfd54584919dddbe55cef7c8459684/velocity_stop.cpp Try hacking the Box2D source that is copy pasted inside Urho3D to see how it affects the bouncing.

One workaround is to just make the scene larger. So e.g., the 1.0 world size I was using in my example was too small, but if you use magnitudes along 100.0 as done in the Testbed, things look fine.

Using small bodies also has further related caveats, e.g. the skin size that separates bodies becomes more visible: Rectangles render with gaps in between them (Box2D)

Related: https://stackoverflow.com/questions/5381399/how-can-i-prevent-a-ball-from-sticking-to-walls-in-box2d

\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.