The Game Loop
The game loop is the heartbeat of every game. We used a very rudimentary one so far (you can find it here) without any control over how fast or slow we update our game state and which frames to render. To recapitulate, the most rudimentary game loop is a while loop that keeps executing some instructions until we signal it to finish, usually by setting a variable called running to false
boolean running = true;
while (!running)
{
updateGameState();
displayGameState();
}
The above code runs blindly without a care for timing and resources. If you have a fast device then it will run very fast and if you have a slow one it will run slower.
The updateGameState() updates the state of every object in the game and the displayGameState() renders the objects into an image which is displayed onto the screen.
There are two things we should consider here: FPS and UPS.
FPS – Frames per Second – the number of times displayGameState() is being called per second.
UPS – Update per Second – the number of times updateGameState() is being called per second.
Ideally the update and render methods will be called the same number of times per second (preferably not less than 20-25 times per second). 25 FPS is usually enough on a phone so us humans won’t notice the animation being sluggish.
For example if we target 25 FPS then it means we have to call the displayGameState() method every 40ms (1000 / 25 = 40ms, 1000ms = 1s). We need to bear in mind that updateGameState() is also called before the display method and for us to reach 25 FPS, we have to make sure that the update – display sequence executes in exactly 40ms. If it takes less than 40ms, then we have a higher FPS. If it takes more than that, then we have a slower running game.
Let’s see some examples to understand the FPS better.
The following diagram shows exactly 1 FPS. It takes the update – render cycle exactly one second to execute. This means that you will see the image on the screen change once every second.
The following diagram shows 10FPS. An update – render cycle takes 100ms. This means every tenth of a second the image changes.
But the above scenario means that the update-render cycle executes in 1/10 of a second EVERY time. That is an assumption and we can’t control the actual times on cycle executes, or can we? What happens if we have 200 enemies and every enemy is shooting at us? We need to update the state of each enemy and the states of their bullets and check for collisions in one single update. It’s different when we have just 2 enemies. The times will clearly differ. The same applies to the render method. Rendering 200 firing droids will clearly take more time than rendering only 2.
So what are the scenarios? We could have an update-render cycle that finishes in less than 100ms (1/10 of a second), finishes in exactly 100ms or finishes in more than that. On a powerful hardware it will be faster than on a weaker one. Let’s see the diagrams.
The cycle finishes before the desired timeframe so we have a small amount of free time before running the next cycle.
The following diagram shows a cycle which falls behind. That means that the time it takes for a update-render cycle to finish is greater than the desired one. If it takes 12ms that means we are 2ms behind (still considering the 10FPS). This can mount up and every cycle we loose time and the game will run slowly.
The first situation is the desired one. This gives us some free time to do something before we kick off the next cycle. We don’t need to do anything so we just tell the game loop to go to sleep for the remaining time period and wake up when the next cycle is due. If we won’t do this the game will run quicker than intended. By introducing the sleep time we achieved constant frame rate.
The second situation (I skipped the ideal one as it almost never happens) when the loop is behind, requires a different approach.
To achieve constant speed in a game we need to update the state of our objects when required. Imagine a droid approaching you at a constant speed. You know if it travelled half the screen in one second, so it will take another second to reach the other side of the screen. To calculate the position accurately we need to know either the time delta since the last postion, and the current speed of the droid, or we update the position (status) of the droid at constant intervals. I will choose the second one as playing with deltas in the game update can be tricky. To achieve a constant game speed we will have to skip displaying frames. Game speed is NOT FPS!
Examine the following diagram. It is a scenario in which the update-render cycle takes longer than the desired time so we have to catch up. To do that we will skip the rendering of this frame and will do another update so the game speed won’t be affected. We’ll do a normal cycle in the next frame with even some time to give to the CPU to rest.
The above scenario has many variations. You can imagine the game update taking more than one full frame. In this case we can do nothing to keep the game speed constant and the game will run slower. We might have to skip multiple renderings to keep the speed constant but we have to make sure that we set the maximum number of frames allowed to be skipped because it can take quite a few updates to catch up and in case we skipped 15 frames that means we lost a lot from the game and it will just be unplayable.
The MainThread.java‘s run() looks like this:
// desired fps
private final static int MAX_FPS = 50;
// maximum number of frames to be skipped
private final static int MAX_FRAME_SKIPS = 5;
// the frame period
private final static int FRAME_PERIOD = 1000 / MAX_FPS;
@Override
public void run() {
Canvas canvas;
Log.d(TAG, "Starting game loop");
long beginTime; // the time when the cycle begun
long timeDiff; // the time it took for the cycle to execute
int sleepTime; // ms to sleep (<0 if we're behind)
int framesSkipped; // number of frames being skipped
sleepTime = 0;
while (running) {
canvas = null;
// try locking the canvas for exclusive pixel editing
// in the surface
try {
canvas = this.surfaceHolder.lockCanvas();
synchronized (surfaceHolder) {
beginTime = System.currentTimeMillis();
framesSkipped = 0; // resetting the frames skipped
// update game state
this.gamePanel.update();
// render state to the screen
// draws the canvas on the panel
this.gamePanel.render(canvas);
// calculate how long did the cycle take
timeDiff = System.currentTimeMillis() - beginTime;
// calculate sleep time
sleepTime = (int)(FRAME_PERIOD - timeDiff);
if (sleepTime > 0) {
// if sleepTime > 0 we're OK
try {
// send the thread to sleep for a short period
// very useful for battery saving
Thread.sleep(sleepTime);
} catch (InterruptedException e) {}
}
while (sleepTime < 0 && framesSkipped < MAX_FRAME_SKIPS) {
// we need to catch up
// update without rendering
this.gamePanel.update();
// add frame period to check if in next frame
sleepTime += FRAME_PERIOD;
framesSkipped++;
}
}
} finally {
// in case of an exception the surface is not left in
// an inconsistent state
if (canvas != null) {
surfaceHolder.unlockCanvasAndPost(canvas);
}
} // end finally
}
}
Examine the above code very carefully as it implements the logic behind the diagram.
You can find the full code in the downloadable project.
There is another approach which I like. It is constant game speed with maximum number of frames per second. It uses interpolation to draw the state and it occurs on fast hardwares when there is time left for another rendering before the next game update. This can enhance the visuals of a game as it enables smoother animation but because we use mobile devices, giving the CPU some rest will save the battery quite a lot.
There is an awesome article on game loops here. I personally understood the game loops reading this article so I highly recommend it. The best I could find.
Note that I also modified the default values in the Speed.java class. The speed is measured in units/second.
Because we are setting our desired FPS to 50 that means that the speed will increase by 50*speed.value every update. To have the speed of let’s say 40 pixels/second you will need to set the speed delta for every tick to 2 (40 / (1000 / 50) = 2). In other words you need the droid to advance 2 pixels every game update (when you have 50 game updates per second) to cover 40 pixels per second.
Examine it and you have a constant game speed with variable frame rate.
To see how we measure the FPS check the next entry.





Great code. There is a problem when u press home or back button and u come back in the app. I fixed in this way:
@Override
public void surfaceCreated(SurfaceHolder holder) {
//if it is the first time the thread starts
if(thread.getState() == Thread.State.NEW){
thread.setRunning(true);
thread.start();
}
//after a pause it starts the thread again
else
if (thread.getState() == Thread.State.TERMINATED){
thread = new MainThread(getHolder(), this);
thread.setRunning(true);
thread.start(); // Start a new thread
}
}
and this
@Override
protected void onPause() {
Log.d(TAG, “Pausing…”);
MainThread.running=false;//this is the value for stop the loop in the run()
super.onPause();
}
making the “running” variable, static
Thank you!
How would you handle touch events with this? Currently my update() call is done outside my main game thread because it is called directly from a touch listener is the main game activity. How would I get the update() call away from the touch listener and into my thread? Would I need to save the calls from touch listener elsewhere, to be consumed during an update() call from the thread?
You have a good way of explaining this matter clearly. I think your next project should be to bundle all your tutorials into a book (PDF) about 3D Android game programming
Hey, Great Work! Dude your tutorials help me, a high school-student, learn game programming.
But there is a question of mine over FPS thing.
I, by applying similar algorithm, got to know the default FPS of the game on my device Samsung Galaxy S3. Please note that its just default for what my phone gives.
So the result came out to be 30 FPS approx. (And the animations were extremely fluid.)
But now when I use your algorithm with MAX_FPS = 30 the game on my S3 is sluggish!
Why is that happening if everything was same itself?
And when I put MAX_FPS = 55 the game gets better. (With relatively better fluidity).
I’ll be extreme glad if you could help me.
Thanks.
Thank you for providing this great tutorial:D
but i have a question regarding the elapsed time.
should’t we put
beginTime = System.currentTimeMillis();
right after
timeDiff = System.currentTimeMillis() – beginTime; ?
because all those sleeptime checking,frameskipping will still consuming some millisecond and i think we should add all this into the calculation of elapsed time as well.
please help ~
Great article!
Used it as starting point for my first game. However I stumbled across a synchronization problem when using Tread.sleep(). Solved by using surfaceHolder.wait() instead.
http://www.giskeskaaren.com/wordpress/?p=99
Your articles are rightly paced for someone new to android. Very good for learning !!!
Last paragraph of above article is confusing for me.
1) “If desired FPS is 50, speed will increase by 50*speed.value every update” ??
Speed of droid should be constant according to me.
2) “droid to advance 2 pixels every game update (when you have 50 game updates per second) to cover 40 pixels per second” ??
If it travels 2 pixels every update and in total 50 updates happen in a second, then it will travel 2*50=100 pixels and not 40 pixels ??
Please help me understand this.
Your articles are rightly paced for someone new to android. Very good for learning !!!
Last paragraph of above article is confusing me. Last Paragraph says:
“Because we are setting our desired FPS to 50 that means that the speed will increase by 50*speed.value every update. To have the speed of let’s say 40 pixels/second you will need to set the speed delta for every tick to 2 (40 / (1000 / 50) = 2). In other words you need the droid to advance 2 pixels every game update (when you have 50 game updates per second) to cover 40 pixels per second.”
My Doubts
1) “If desired FPS is 50, speed will increase by 50*speed.value every update” ??
Speed of droid should be constant
2) “droid to advance 2 pixels every game update (when you have 50 game updates per second) to cover 40 pixels per second” ??
If it travels 2 pixels every update and in total 50 updates happen in a second, then it will travel 2*50=100 pixels and not 40 pixels ??
Please help me understand this.
Your articles are rightly paced for someone new to android. Very good for learning !!!
Last paragraph of above article is confusing me.
Last Paragraph says:
“Because we are setting our desired FPS to 50 that means that the speed will increase by 50*speed.value every update. To have the speed of let’s say 40 pixels/second you will need to set the speed delta for every tick to 2 (40 / (1000 / 50) = 2). In other words you need the droid to advance 2 pixels every game update (when you have 50 game updates per second) to cover 40 pixels per second.”
My Doubts
1) “If desired FPS is 50, speed will increase by 50*speed.value every update” ??
Speed of droid should be constant
2) “droid to advance 2 pixels every game update (when you have 50 game updates per second) to cover 40 pixels per second” ??
If it travels 2 pixels every update and in total 50 updates happen in a second, then it will travel 2*50=100 pixels and not 40 pixels ??
Please help me understand this.
Great tutorials!
Can you tell me how System.currentTimeMillis() – beginTime gives the cycle time, though? its says is returns the time since 1970??
Thanks
Great tutorial, explained very clearly. Keep up the good work!
However, can you describe how:
System.currentTimeMillis() – beginTime gives the time taken for that cycle, timeDiff (update + draw time, as I understand it). Doesn’t System.currentTimeMillis() return the time since 1970???
Thanks
beginTime gets the value just before the update and drawing happens. Check line 27.
It’s only a reference.
timeDiff is the difference between the reference time and the current time.
So when starting the measurement at X point in time, which is today at 12:00.00 for example (this is what currentTimeMillis() gives) and the update with the rendering takes up 3 seconds, the timediff will be:
currentTime since 1970 minus the time the update has started (begin time).
Which gives you 3 seconds as 12:00.03 – 12:00.00 = 3 seconds.
Perfect
Thanks again. You can delete my other post – my browser was playing up so tried again :S
Thanks for the great tutorials. I’m just learning and I keep running into similar issues when I leave the app and try to resume it. This isn’t the only game loop template / tutorial I run into issues doing this.
I’m running in android 2.3.3 and everything works fine I can click the bottom the the screen and the game exits like it should. However if instead I press the home button then click the app icon again to resume it the game looks like its working with the robot bouncing around but it no longer accepts any click events. The debugger doesn’t even go into onTouchEvent(MotionEvent event). If I keep tapping the screen I can sometimes get android to popup a message saying the application has stopped responding and allow me to force close it.
Any ideas whats going on and how to solve it?
Thanks!
[...] When in android should I place main game loop in the initial activity class? I’m trying to create a game loop using this tutorial. [...]
Excellent excellent tutorial! Couple of questions, in the last ‘while’ loop what is the purpose of the line:
“sleepTime += FRAME_PERIOD;”
Wouldn’t this just set sleepTime back to your target interval (frame period) and therefore mean that the loop will never run more than once? I must have it wrong! But would be grateful if someone could explain
Lastly, I’ve got this running on my test device and also on the emulator, now I know the eumlator is s-l-o-w and I get only about 10FPS on it compared to 60fps on my device (I’m running this with my target frame period set to 16ms) but on the emulator, my object takes twice as long to go from the bottom to the top – should it not take the same amount of time, but appear a lot ‘chooppier’/jerky??
Thanks again for any help you could offer!!
If you set a frame period of 20ms and a cycle takes 60ms to run, the sleep time will be -40ms. If you then update the panel and add the frame period to the sleep time, the new sleep time will be -20ms which is still less than 0 so the loop will run again.
That said, I’m not sure I understand the logic either. If the sleep time is -10ms and the following render-less update takes 15ms to complete, no further frames will be skipped (since the 20ms frame period added to the -10ms sleep time exceeds 0) but the next normal cycle will start 5ms later than it should have.
I believe the amount of time the update takes should be taken into account.
Shouldn’t it be:
long updateBeginTime = System.currentTimeMillis();
this.gamePanel.update();
long updateTimeDiff = System.currentTimeMillis() – updateBeginTime;
sleepTime = (FRAME_PERIOD + sleepTime) – updateTimeDiff;
framesSkipped++;
That way, if the first render-less update cuts into the next frame, sleepTime will be set to a number less than 0 and another render will be skipped.
Can someone confirm whether or not my method makes sense? I don’t really have any experience with this.
[...] It maintains the frame rate of our game. Here’s a good article regarding the game loop: http://obviam.net/index.php/the-android-game-loop/. Also, write a new class inheriting the SurfaceView class. I’ve called mine [...]
[...] particually in the Killer Game Programming in Java book and in this tutorial I just found: Here Just a simple, timed gameloop with a back [...]
[...] trying to implement a SurfaceView, calling its onDraw() method from a Thread, based on this tutorial. My app is giving ANR after I start the below code [...]
Hello,
one small question:
Why do you set the complette gameloop-body into a synchronized block?
greetings
As the renderer and the update methods run in separate thread and both access the same instances of game objects, I have to take care that no object is modified by 2 threads at the same time.
Failing to do so, will result in exceptions.
Suppose I had the View and Thread running in the same file how would I set up the game-loop body. Because I put both in the same file so I could understand most examples I see better. Thanks a lot though for the tutorials, it makes a lot of things easier to get.
You mean the View and GameLoop to run in the same thread? Or do you mean creating the Thread as an innerclass for the view?
In the first case, you will call the update just before the render and it will be sequential.
Creating the thread as a innerclass of for the view.
For this you will just have to move the content of the file containing the thread into your main file. But I wouldn’t do that as it can get cluttered and hard to read.
You might want to look up how to use volatile variables to handle concurrency as well if yo will access shared data.
Very cool. I’m more into the graphics design and 3d modeling but I’ve been trying to get into the coding so I can do it all myself if necessary. Shoot me an email if you’d ever like to work on a bigger project and would like some graphic/art help. Meanwhile I’m going to finish your tutorials and then on to the next ones I can find! You have been great, these are the best tutorials on Android games I’ve found so far!
Thanks again!
you have another typo.
Where you say “If it takes 12ms that means we are 2ms behind (still considering the 10FPS).”
I think you meant to say “If it takes 102 ms…….”
Thank you for the amazing tutorial to make me start gaming in android !!!
This series of tutorial are awesome and I have a question about send value to Activity, hope you can help me.
I recoded your example “The Game Loop” and made it become a game that user can destroy robots by touch to increase score,
the question is how can I send score to next Activity ?
because I want to let user decide play again or not and show the score with it.
In the usual way there is a button in OnCreate and with an OnClickListener,
but in this case, I don’t know how to do.
Thank you.
You say that with 2 pixels per update we get 4 pixels a second with 50 updates a second. However 2 pixel per update times 50 updates per second = 100 pixels per second (2*50=100). To get 40 pixels a second we need 50 updates per second divided by 40 pixels per second = 0.8 pixels per update (50/40=0.8).
I’m not sure I get what you mean but here is what I understood.
You will be displaying an image in a render cycle. If you want to have a 50 fps renderer you have to display the image (the whole screen is an image) every 1000/50 = 20 millisecond.
An image can consist of multiple pixels. A typical HVGA is 480×320 = 153.600 pixels.
That many pixels are drawn to the screen every 20 ms in case of a 50 fps.
Hope this clarifies it a bit.
Hi,
Thats really informative…
i must appreciate your effort
i have a question or help you can say.
in your example to explain game loop.. you are calling
this.gamePanel.render(canvas);
for drawing…
but if i use OpenGL ES, how can i control this step… since Renderer has OnDrawFrame. which runs automatically….
this.gamePanel.render(canvas);(internally it call to draw bitmap)
is a synchronous call i believe, that’s the reason why we are able to calculate time to update & draw and then sleep in extra time….
how can i achieve this with OpenGL ES, with Renderer??
it would be great help.
Hi there,
That is a very good question. In the next set of articles I will be switching to OpenGL and indeed, the render cycle is not controllable from within the main thread.
I will introduce a delta and will use interpolation to display the correct positions of the objects.
It will be interesting as it will include volatile variables to work across threads and multi-threading will have to be done properly.
I’m actually working on some proof of concepts and will write about them as soon as everything is in place and working.
The update and render will work independently.
Good observation!
Hi,
Thanks for reply….
i hope that article will come soon…
Thanks a lot for your tutorial. I have had experience programming graphics before using SlimDX and SDL but I was unsure how to get to that point of control on Android. Your walk through has been invaluable!
I thought you’d like to know you have a little typo:
“The following diagram shows 10FPS. An update – render cycle takes 10ms. This means every tenth of a second the image changes.”
10ms should read 100ms.
Thanks for the correction. I have amended it.
Thank you for the tutorial, great intro-tutorial for starters.
very cool, article, began to understand the game design a bit.
thanks