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?