Search Tips Advanced Search |
| Delphi Graphics and Game Programming Exposed with DirectX 7.0 by John Ayres Wordware Publishing, Inc. ISBN: 1556226373 Pub Date: 12/01/99
Search this book:
Previous | Table of Contents | Next
### The Game Loop As mentioned above, the actual game loop is usually the focal point of a game application. The game loop is where all of the action takes place. It processes a series of instructions over and over as quickly as possible to produce the on- screen images that reflect the current state of the game. This processing continues with or without user interaction, and is precisely the method by which the real-time event-driven model discussed previously is implemented. Technically speaking, a game loop is responsible for three things: retrieving input, updating game objects, and rendering a new frame of animation. Of course, there’s a lot more to a game loop than this oversimplified description suggests. What actually occurs in a game loop is very arbitrary and will depend on the needs of the individual game. However, all games perform similar tasks, usually in a similar order. Expanding upon the three tasks listed above, Figure 2-2 illustrates an example game loop that might be found in a simple action arcade game. Figure 2-2: A simplistic game loop There are several different techniques by which this game loop architecture could be implemented. In the examples in this book, we will be implementing the primary game loop inside the Application.OnIdle event. This technique is used for several reasons. First, the main game loop will automatically be entered whenever the application becomes idle (after initializing everything in the OnCreate or OnActivate form event handlers or the initialization section of the unit). Second, the application object controls when the OnIdle event is called, meaning that any standard Windows events will be processed and the application never needs to call Application.ProcessMessages. Third, it’s simply an easy, Delphi-centric technique for implementing the game loop that should be easy to understand and reproduce. Alternatively, a while..do or repeat..until loop could be used to implement the game loop. The advantages of this technique are that the developer will have more control over the application, and it will run a little faster than the OnIdle technique. The application could even exit the game loop for some reason, perhaps to display a simple options screen that didn’t need the complex animation capabilities afforded by the game loop. The disadvantages to this method of game loop implementation are that these types of loops are generally a little harder to work with when trying to support general Windows events. Application.ProcessMessages must certainly be called at some point within the loop so that standard Windows messages can be handled. Also, the variable controlling the loop’s execution must be set so that the loop can exit before the application can terminate; simply calling Close or Application.Terminate will not work. Using this technique can result in little issues such as these that interfere with the normal operation of a Windows application. They can usually be handled with minor workarounds, however, so using a loop such as this may be advantageous depending on the type of game being produced. The following listing demonstrates an implementation of the arbitrary game loop using a while..do loop. Listing 2-1: Arbitrary game loop example
    procedure GameLoop;

    var

      TimeStart: Longint;   // used to time the length of one loop iteration

    begin

      {this while..do loop will continue processing the same commands in

       rapid succession until instructed to exit from the loop}

      while GameRunning do

      begin

        {record the current time upon starting the loop}

        TimeStart := GetCurrentTime;

        {retrieve input from the user by accessing whichever input device

         the user has chosen}

        RetrieveInput;

        {perform any enemy artificial intelligence and other logic

         associated with game elements not controlled by the user}

        PerformEnemyAI;

        {iterate through all sprites, updating their positions accordingly,

         taking into account user input and enemy AI calculations}

        UpdateSpritePositions;

        {check for any collisions between objects that would result in a

         change in the current game state, such as missiles colliding with a

         target or the player’s sprite impacting a wall or other object}

        CheckForCollisions;

        {start any sound effects needed, based on collision detection or

         other game states}

        StartSounds;

        {start any music needed, again based on collision detection or other

         game states}

        StartMusic;

        {all processing has been completed, so draw the current state of the

         game to the screen}

        DrawFrame;

        {determine if the game is still running, based on whether the player

         has died or some other deciding threshold has been reached}

        GameRunning := IsGameOver;

        {determine how long this cycle has taken; if it has been too short,

         pause for the difference so that the game does not run too fast}

        If GetCurrentTime-TimeStart<TimingValue then

            Pause(GetCurrentTime-TimeStart);

        {process any Windows messages that are waiting}

        Application.ProcessMessages;

      end;  // repeat this process over and over until the game has ended

    end;
As a matter of practice, several of these tasks may be combined or performed simultaneously. For example, since an application must iterate through every game object to update its position, it would be practical to draw each object as its position is updated. Also, collisions usually result in an object being destroyed or its course being altered, so appropriate sound effects could be started at the time of the collision detection. The point is that these steps represent an arbitrary game loop, and may be rearranged or combined (or even split apart) as the individual circumstances warrant. Even with this expanded view of a game loop implementation, many of the details attended to within the loop are not fully exposed. Throughout this book, we will examine many game examples that contain highly varied game loops, containing various functions as required by the individual game type. Later chapters will discuss in depth the tasks performed by an individual game example’s game loop, but for now, let’s examine an overview of what each segment is responsible for within our arbitrary game loop. #### Retrieve User Input Retrieving user input involves reading the input values from whatever device is supported or that the user has chosen, and translating that information into a form relevant to the control of the game. Most Delphi applications typically handle user input through event handlers, such as OnKeyDown or OnMouseMove. For business applications and even most strategy or turn-based games, this method is fine. However, fast action arcade games typically require more control over the process, and handling user input through events may impede or interfere with the proper execution of the game.
Previous | Table of Contents | Next

Products | Contact Us | About Us | Privacy | Ad Info | Home Use of this site is subject to certain Terms & Conditions, Copyright © 1996-2000 EarthWeb Inc. All rights reserved. Reproduction whole or in part in any form or medium without express written permission of EarthWeb is prohibited. Read EarthWeb's privacy statement.