Question

I'm trying make a sample with box2d in libgdx.

I want the ball fall with gravity in box2d world. Now it fall but without acceleration (I see the ball is falling with acceleration =0) . I tried to add Damping, density... but there are no changes. Please help me find my fault. Thank you so much.
This's the video for this issue: youtube.com/watch?v=NkbcVMsB2S0
; In this video you can see the circle is falling with acceleration=0. I tried to change some parametters, but look like acceleration is always zero. This's a simple class:

public class MyGdxGame implements ApplicationListener, InputProcessor {
World world;
Box2DDebugRenderer debugRenderer;
OrthographicCamera camera;
static final float BOX_STEP = 1 / 45f;
static final int BOX_VELOCITY_ITERATIONS = 6;
static final int BOX_POSITION_ITERATIONS = 2;
static final float WORLD_TO_BOX = 0.01f;
static final float BOX_WORLD_TO = 100f;

private int counter = 100;
private Body body;

@Override
public void create() {
    world = new World(new Vector2(0, -200f), false);
    world.setContinuousPhysics(true);
    camera = new OrthographicCamera();
    camera.viewportHeight = 320;
    camera.viewportWidth = 480;
    camera.position.set(camera.viewportWidth * .5f,
            camera.viewportHeight * .5f, 0f);
    camera.update();
    // Ground body
    BodyDef groundBodyDef = new BodyDef();
    groundBodyDef.position.set(new Vector2(0, 10));
    Body groundBody = world.createBody(groundBodyDef);
    PolygonShape groundBox = new PolygonShape();
    groundBody.createFixture(groundBox, 0.0f);
    // Dynamic Body
    BodyDef bodyDef = new BodyDef();
    bodyDef.type = BodyType.DynamicBody;
    bodyDef.position.set(camera.viewportWidth / 2, camera.viewportHeight);
    bodyDef.angularDamping = 0.01f;
    bodyDef.linearDamping = 0.0f;
    body = world.createBody(bodyDef);
    CircleShape dynamicCircle = new CircleShape();
    dynamicCircle.setRadius(10f);
    FixtureDef fixtureDef = new FixtureDef();
    fixtureDef.shape = dynamicCircle;
    fixtureDef.density = 10.0f;
    fixtureDef.friction = 0.0f;
    fixtureDef.restitution = 0f;
    body.createFixture(fixtureDef);
    MassData massData = new MassData();
    massData.mass = 50f;
    body.setMassData(massData);
    body.setGravityScale(1f);
    debugRenderer = new Box2DDebugRenderer();
    Gdx.input.setInputProcessor(this);
}

@Override
public void dispose() {
}

@Override
public void render() {
    Gdx.gl.glClear(GL10.GL_COLOR_BUFFER_BIT);

    if (counter < 10) {
        body.applyForceToCenter(0, 200000f, true);
    }
    counter++;
    debugRenderer.render(world, camera.combined);
    world.step(BOX_STEP, BOX_VELOCITY_ITERATIONS, BOX_POSITION_ITERATIONS);
}

@Override
public void resize(int width, int height) {
}

@Override
public void pause() {
}

@Override
public void resume() {
}

@Override
public boolean keyDown(int keycode) {
    // TODO Auto-generated method stub
    return false;
}

@Override
public boolean keyUp(int keycode) {
    // TODO Auto-generated method stub
    return false;
}

@Override
public boolean keyTyped(char character) {
    // TODO Auto-generated method stub
    return false;
}

@Override
public boolean touchDown(int screenX, int screenY, int pointer, int button) {
    counter = 0;
    return false;
}

@Override
public boolean touchUp(int screenX, int screenY, int pointer, int button) {
    return false;
}

@Override
public boolean touchDragged(int screenX, int screenY, int pointer) {
    // TODO Auto-generated method stub
    return false;
}

@Override
public boolean mouseMoved(int screenX, int screenY) {
    // TODO Auto-generated method stub
    return false;
}

@Override
public boolean scrolled(int amount) {
    // TODO Auto-generated method stub
    return false;
}
Was it helpful?

Solution

I think that's because the body is instantly at maximum velocity (because of the very high gravity). Box2D has a maximum velocity and I think it's 2m per step. It seems that you run it on a mobile device which are usually limited to 60FPS. That means that you have max 60 update steps per second, resulting in a maximum velocity/speed of 120m/s. By the way, your update rate is framerate dependent.

I see that you have defined the meter-to-pixel and pixel-to-meter constants, but you aren't using them anywhere in your code. That means that you are using a meter-to-pixel ratio of 1:1 and thus the maximum speed any body can have is 120px/s. That's not a lot and judging by that video it could be correct.

A common trick is to scale your camera's viewport down instead of scaling all box2d related things up. Like this:

camera.viewportHeight = Gdx.graphics.getHeight() * WORLD_TO_BOX;
camera.viewportWidth = Gdx.graphics.getWidth() * WORLD_TO_BOX;

OTHER TIPS

I had simmilar problem. In my case the solution was to change the value of BOX_STEP parameter to 1/240 (it used to be 1/60 and then the max linear velocity was 120)

static final float BOX_STEP=1/240f;
static final int BOX_VELOCITY_ITERATIONS=20;
static final int BOX_POSITION_ITERATIONS=3;

so in the renderer() step now takes the above

world.step(BOX_STEP, BOX_VELOCITY_ITERATIONS, BOX_POSITION_ITERATIONS);

I also introduced the noone answear but without changes to the step method it wasn't working

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top