2
\$\begingroup\$

I am running a simple Libgdx app that I have wrote, on my Android phone and Android tablet and I am getting the unexpected result of having different velocities when a body is moved. To move the body I am using a "drag" movement in this way (snippet):

private Body ballBody;
private int ballX1, ballY1;

@Override
public boolean touchDown(int screenX, int screenY, int pointer, int button) {
    ballX1 = screenX;
    ballY1 = screenY;
    return true;
}

@Override
public boolean touchUp(int screenX, int screenY, int pointer, int button) {
    Vector2 v2 = new Vector2(ballX1 - screenX, screenY - ballY1);
    v2.scl(0.25f);
    ballBody.setLinearVelocity(v2);
    return true;
}

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

Render part with some of my attempts to fix delta-time and FPS:

private static final int SCREEN_HEIGHT = 16; //320;
private static final int SCREEN_WIDTH = 24; //480;
private static final int BOX_VELOCITY_ITERATIONS = 6;
private static final int BOX_POSITION_ITERATIONS = 2;
private static final float BALL_RADIUS = 0.1f;
private static final float MAX_FPS = 1 / 60f;
private static final float PIXELS_TO_METERS = 20f;
private static final long ONE_SECOND_NS = 1000000000;

private int maxUpdates = 10;
private long lastTime = System.nanoTime();
private World world = new World(new Vector2(0, -9.8f), true);

@Override
public void render() {
    ballIsNotMoving = ballIsNotMoving();
    if (ballIsNotMoving && ballBody.getPosition().x > landscape2d[20] && ballBody.getPosition().x < landscape2d[28]) {
        newHole();
    } else if (ballBody.getPosition().x > SCREEN_WIDTH + ball.getWidth() / 2 || ballBody.getPosition().x < - ball.getWidth() / 2) {
        resetBallPosition();
    }

    camera.update();
    Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT);
    Gdx.gl.glClearColor(34/255f, 167/255f, 240/255f, 0);

    fixTimeStep();

    world.step(MAX_FPS, BOX_VELOCITY_ITERATIONS, BOX_POSITION_ITERATIONS);

    shapeRenderer.setProjectionMatrix(camera.combined);

    // Set the sprite's position from the updated physics body location
    ball.setPosition(
            ballBody.getPosition().x - ball.getWidth() / 2,
            ballBody.getPosition().y - ball.getHeight() / 2);

    polySpriteBatch.setProjectionMatrix(camera.combined);
    polySpriteBatch.begin();
    pitch.draw(polySpriteBatch);
    polySpriteBatch.end();

    createStartArea(shapeRenderer);

    fixFPS();

//        debugRenderer.render(world, camera.combined);
}

private boolean ballIsNotMoving() {
    float speedNow = ballBody.getLinearVelocity().len();
    recentSpeed = 0.1f * speedNow + 0.9f * recentSpeed;
    if (recentSpeed < 0.20f) {
        stopBallMovement();
        return true;
    }
    return false;
}

private void fixTimeStep() {
    long time = System.nanoTime();
    long timeDelta = time - lastTime;
    float timeDeltaSeconds = timeDelta / (float) ONE_SECOND_NS;
    lastTime = time;

    // Update the game state in capped time steps (in case we're running too slow)
    int updateCount = 0;
    while (timeDelta > 0 && (maxUpdates <= 0 || updateCount < maxUpdates)) {
        // Update using a time step in seconds
        float updateTimeStep = Math.min(timeDeltaSeconds, ONE_SECOND_NS * MAX_FPS);
        float updateTimeStepSeconds = updateTimeStep / (float) ONE_SECOND_NS;

        world.step(updateTimeStepSeconds, BOX_VELOCITY_ITERATIONS, BOX_POSITION_ITERATIONS);

        timeDelta -= updateTimeStep;
        updateCount++;
    }
}

private void fixFPS() {
    long sleepTime = Math.round((ONE_SECOND_NS / MAX_FPS) - (System.nanoTime() - lastTime));
    if (sleepTime <= 0)
        return;
    long prevTime = System.nanoTime();
    while (System.nanoTime() - prevTime <= sleepTime) {
        try {
            Thread.sleep(1);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }
}

The app start with the same resolution for both devices. Any idea about how to get the same speed?

\$\endgroup\$
2
  • \$\begingroup\$ can you show us your render method? \$\endgroup\$
    – Erez
    Commented Mar 10, 2015 at 7:26
  • \$\begingroup\$ @Erez added render \$\endgroup\$
    – Randomize
    Commented Mar 10, 2015 at 21:22

2 Answers 2

2
\$\begingroup\$

Stop using pixels and use virtual units. Remember that if you don't have camera.unproject(); in your input processing code, then you have bad input processing code.

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

LibGdx is taking care of the FPS itself, there's no need to for you to intervene.

remove all the fixing methods, your delta time is now -

gdx.graphics.getDeltaTime()

use only it (send it to world.step())

\$\endgroup\$
1
  • \$\begingroup\$ If you mean just using this: world.step(Gdx.graphics.getDeltaTime(), BOX_VELOCITY_ITERATIONS, BOX_POSITION_ITERATIONS); it doesn't work, still the same problem \$\endgroup\$
    – Randomize
    Commented Mar 11, 2015 at 19:12

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .