Game Loop is an important part of any game and is responsible for making sure that your game performs all the right functions at the right time and in the right order.There are a number of core activities that a game loop must do, such as the following:
1. Take input from the user.
2. Update the state of the player based on the user’s input.
3. Update the state of the other entities in the game, such as baddies.
4. Check for collisions between entities.
5. Render the game to the screen.
This is not all the items that need to be handled within a game loop, but it is an example of what needs to be done.The game loop is responsible for making sure that even when the player is not doing anything, the rest of the game is being updated. For example, the baddies(坏蛋) are still moving around, ambient (周围的,环绕的)sounds still play, and so on.
You may read about game cycles, tick count, and so on, but they are all referring to the game loop or iteration through that loop.
At its most basic level, the game loop is exactly that—a loop—and functions are called within that loop for things that make the game tick.We will create our own game loop for Sir Lamorak’s Quest in Chapter 4,“The Game Loop,” but as we have been through somuch and not seen a single line of code, I thought it might be helpful to put the basicgame loop code here in Listing 2.1.The idea here is not for you to fully grasp what’s going on within that loop. My intent is to show you that a simple game loop can actually bevery small.
Listing 2.1 The Game Loop
#define MAXIMUM_FRAME_RATE 120
#define MINIMUM_FRAME_RATE 30
#define UPDATE_INTERVAL (1.0 / MAXIMUM_FRAME_RATE)
#define MAX_CYCLES_PER_FRAME (MAXIMUM_FRAME_RATE / MINIMUM_FRAME_RATE)
- (void)gameLoop {
static double lastFrameTime = 0.0f;
static double cyclesLeftOver = 0.0f;
double currentTime;
double updateIterations;
// Apple advises to use CACurrentMediaTime() as CFAbsoluteTimeGetCurrent() is
// synced with the mobile network time and so could change causing hiccups.
currentTime = CACurrentMediaTime();
updateIterations = ((currentTime - lastFrameTime) + cyclesLeftOver);
if(updateIterations > (MAX_CYCLES_PER_FRAME * UPDATE_INTERVAL))
updateIterations = (MAX_CYCLES_PER_FRAME * UPDATE_INTERVAL);
while (updateIterations >= UPDATE_INTERVAL) {
updateIterations -= UPDATE_INTERVAL;
// Update the game logic passing in the fixed update interval as the delta
[sharedGameController updateCurrentSceneWithDelta:UPDATE_INTERVAL];
}
cyclesLeftOver = updateIterations;lastFrameTime = currentTime;
// Render the scene
[self drawView:nil];
}
The loop shown in Listing 2.1 is an open loop, which means it runs at regular intervals using a timer external to the loop.The other type of game loop is called a tight loop. Once a tight loop starts, it continues to loop as fast as it can, running code within the loop over and over again.There are benefits and drawbacks to both methods, and the one you usewill greatly depend on the type of game you are writing (more on this in Chapter 4).
The second function of the game loop is to make sure that the game runs at a constant speed. If you were to run a tight loop that just went as fast as it could, you would have a game in which objects would move around the screen faster on quick hardware ands lower on slow hardware.This isn’t something you want to happen.You want to give theplayers of the game a consistent experience regardless of the hardware the game is run-ning on.
For the iPhone, it is a little easier, as we are dealing with a limited number of device types:
iPhone (first generation, or Gen1)n iPhone 3G
iPhone 3GS
iPhone 4
iPod Touch (first generation, or Gen1)
iPod Touch (second generation, or Gen2)n iPad
Although similar, each device is different. For example, the iPhone 4 is faster than theiPhone 3GS, which is faster than the iPhone 3G, and the Gen2 iPod Touch is significantlyfaster than the iPhone 3G.The game loop is where we can handle these differences.
At its simplest, the game loop measures the amount of time, normally in milliseconds,that passes between each loop.The amount of time between each loop is called the delta.
This delta value is then passed to the functions that update the logic of the entities within the game and is used to calculate game elements, such as movement. For example, if you specifyhow far a ghost should move per millisecond, the ghost will only move that far regardless ofthe device’s speed. Sure, the movement will appear smoother on faster devices than slowerones, but the amount of movement, as well as the game play, will be at a consistent speed.