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\$
  • \$\begingroup\$ can you show us your render method? \$\endgroup\$ – Erez Mar 10 '15 at 7:26
  • \$\begingroup\$ @Erez added render \$\endgroup\$ – Randomize Mar 10 '15 at 21:22
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\$
  • \$\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 Mar 11 '15 at 19:12

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.