Game Development Tutorial #1 Smooth Time-Based Movement

This tutorial is part 1 of my fundamental game development concepts series.  In this tutorial we’ll explain the game loop, frame timers, time based movement.

When a hobbyist first begins to develop games they might try to move a character across the screen.  So, the hobbyist checks to see if a user hits the right arrow key and if so, they move the character one pixel to the right.  This will indeed move the character when the key is pressed, but it has a number of limitations.

  1. If each frame takes a different amount of time to render, the character’s movement will be jerky.
  2. The character will move across the screen at a rate dependent on the computer’s processing speed.  If game is running on a faster computer than yours it will run faster than you intended.  The opposite is also true.  If the user is using a slower computer than your development machine the game can be much slower as illustrated in the chart below.

This tutorial will arm you with the knowledge you need to implement professional quality entity movement that takes these concerns into account.

The Game Loop

The game loop is simply a loop that runs forever.  In MOST languages you’ll implement a game loop with a while loop:

while(user hasn’t hit quit) loop over and over..

All of the controller input checking, game state updates, character animations and movements, etc are done in the game loop.

The program runs through the loop as quickly as it can, then begins another loop, and so on until it decides that it’s time to exit.

Below is an example of a typical game loop:

While(quitpressed==false) {

Process controller input;
for example.. if user hits escape then set quitpressed to true, if user hits arrow left then move character left, etc

Update entities;
change characters’ animation frames, make characters in the air fall due to gravity, move a bullet closer to your enemy, etc

Update Graphics;
draw the background, draw sprites, update HUD elements, etc

Update Timer;
update a timer to keep track of when the previous loop completed

}

As you can see the loop will repeatedly check for controller input, update the game’s entities, draw the graphics, and update the timer.  This continues until a condition is met, in this example the loop will continue until quitpressed is set to ‘true’.

Frame Timers and Time Based Movement

Before we go any further we need to define a frame.  A frame is simply a single complete execution of the game loop.

A frame is a single complete execution of the game loop

Let’s say that we want to move a character when the user presses the left or right directions on their game controller.  Instead of simply accepting the key press and moving the character a number of pixels, we need to decide how many pixels we want our character to move over the course of one second.  We may want him to be super fast and move 600 pixels per second, or we may want him to move 5 pixels per second.  By basing his movement around time, we’re able to calculate how much time has elapsed, and how far to move the character so that it’ll move the same speed on every computer.

In order to pull this off we’re going to need to know exactly how much time has traversed since your movement has last been updated.  To do this we utilize our programming language of choice’s timing system.  At the end of every game loop execution (at the end of every frame render) we set a variable equal to the timer at that exact point.  Then, when it’s time to move the character we simply subtract that stored value from the current time to get the difference (the amount of time that has passed since the last frame render).  Let’s look at some pseudo code:

While(quitpressed==false) {

Process controller input;
for example.. if user hits escape then set quitpressed to true, if user hits arrow left then move character left, etc

Update entities;
change characters’ animation frames, make characters in the air fall due to gravity, move a bullet closer to your enemy, etc

Update Graphics;
draw the background, draw sprites, update HUD elements, etc

lastframerendertime = value of current timer;
update a timer to keep track of when the previous loop completed

}

You can see here that we store the value of the timer directly after the frame has rendered.  Usually timers store a decent amount of precision.  It’s important to look at the documentation for the timer variable that you’re using so that you can understand how it stores the data.

Usually timers store data in milliseconds.  There are 1,000 milliseconds in one second.

So, let’s see some pseudo code showing how to calculate the distance in pixels to move the character over the course of one second.

moveDistance = 50;

secondsSinceLastFrame = (currenttimer – lastframerendertimer) / 1000;
this will give us the amount of seconds that have passed, as a decimal number.. you can expect something like .005

characterXPosition = characterXPosition + (moveDistance * secondsSinceLastFrame);

When the moveDistance is multiplied by the fraction of a second that has passed since the last render, you get the amount of pixels that your character should travel in order to achieve a speed of 50 pixels per second.