7
\$\begingroup\$

I've been working on development for an Android game, and this is the game loop I have so far:

private static final int MAX_UPDATES_PER_DRAW = 10;
private long timeAccumulator = 0;
private long lastTime = System.nanoTime();
@Override
public void onDrawFrame(GL10 unused)
{ 
 // Use this structure to set constant dt on a given frame
 // Limit updates to avoid spiral of death;
 long time = System.nanoTime();
 timeAccumulator += time - lastTime;
 lastTime = time;
 int updateCount = 0;
 while (timeAccumulator >= dt && updateCount < MAX_UPDATES_PER_DRAW)
 {
 // Update
 game.update((double) dt / (double) NANOS_PER_SECOND); // Divide by 1 000 000 000 for seconds
 timeAccumulator -= dt;
 updateCount++;
 // Account for any time lost
 time = System.nanoTime();
 timeAccumulator += time - lastTime;
 lastTime = time;
 }
 // Calculate alpha to interpolate between states for smooth animation
 // to avoid temporal aliasing. Alpha ranges from 0.0 - 1.0
 double alpha = Maths.clamp((double) timeAccumulator / (double) dt, 0.0, 1.0);
 // Draw game.
 game.draw(alpha);
 // Check for OpenGL errors.
 int error = GLES20.glGetError();
 if (error != 0)
 throw new RuntimeException("OpenGL Error: " + error);
 // Account for any time lost
 time = System.nanoTime();
 timeAccumulator += time - lastTime;
 lastTime = time;
 // Delay to maintain fps for battery conservation
 long timeUntilUpdate = dt - timeAccumulator;
 if (timeUntilUpdate > 0)
 {
 try
 {
 Thread.sleep(timeUntilUpdate / NANOS_PER_MILI);
 }
 catch (InterruptedException e)
 {
 e.printStackTrace();
 }
 }
}

I'm trying to find a near perfect solution for a fixed time step, but noticing slight stutter (may be due to external reasons like garbage collection) with this one. I plan to break my update(dt) into update(dt) and stepPhysics(dt) and only do a fixed timestep and physics related calculations in stepPhysics to save performance.

Are there any glaring flaws with this that anybody could point out?

Jamal
35.2k13 gold badges134 silver badges238 bronze badges
asked Jul 22, 2014 at 17:29
\$\endgroup\$

1 Answer 1

1
\$\begingroup\$

I don't see where dt is coming from and when it gets updated. You don't modify it within your function, and if its value doesn't change, then there's no need to evaluate this division in every iteration of the while loop:

game.update((double) dt / (double) NANOS_PER_SECOND); 

You could precalculate once before the loop.

Also, in the code I don't see the types of dt and NANOS_PER_SECOND, but if any of them is double, then you don't need the (double) casts. If they are both integers, then it's enough to cast one of them.

The same goes for the casts when you calculate alpha, but this is just a minor style issue, won't improve the performance.

answered Jul 22, 2014 at 18:13
\$\endgroup\$
3
  • \$\begingroup\$ I tried to include the variables defined outside the method but I guess I missed some, yes dt is constant. Yea I guess I could precalculate those things but it would only improve my performance by a tiny fraction. \$\endgroup\$ Commented Jul 22, 2014 at 19:28
  • \$\begingroup\$ If it's a constant, then you should name it with all capitals. But you're right, these changes are unlikely to make a big difference. But every little bit might help. \$\endgroup\$ Commented Jul 22, 2014 at 19:31
  • \$\begingroup\$ It is sort of a constant, but I was considering the possibility of being able to change FPS mid run. I guess there isn't a real situation I would do that (especially in a mobile game) so you're probably right. \$\endgroup\$ Commented Jul 22, 2014 at 19:38

Your Answer

Draft saved
Draft discarded

Sign up or log in

Sign up using Google
Sign up using Email and Password

Post as a guest

Required, but never shown

Post as a guest

Required, but never shown

By clicking "Post Your Answer", you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.