Mega Code Archive

 
Categories / Delphi / Games
 

Constructing inner loop for games

Title: Constructing inner loop for games Question: How to construct an inner loop for games with timing. Answer: The inner loop for games is where the everything happens. In pseudo code it would look something like this: loop start get user input calculate results (game ai, moves, collision, etc) draw everything to the screen wait for loop to restart loop restart At first the TTimer component seems like a good idea to use to make it call the game loop every Nth milliseconds or something like that. However, first of all the TTimer is not as accurate as we wish, but most important, it doesn't care about how long time the code in the loop takes to execute and the result is very jerky (especially noticeable when moving or animating objects). A much better approach is to use the Application.onIdle event and do our own timing within the loop. Setup a handler for the onIdle event by first declare an private procedure: private { Private declarations } procedure OnIdleHandler(Sender: TObject; var Done: Boolean); Then assign the procedure to the event in the form's OnCreate event: procedure TForm1.FormCreate(Sender: TObject); begin Application.OnIdle:= OnIdleHandler; end; The OnIdleHandler is the place for our game loop. In Delphi it's easiest to capture user input with FormKeyDown() events so we really don't have to bother about that in the game loop. The key point of this article is how to do the timing. The thing is to make every flow as smooth as possible to avoid jerky movements and animations, therefore we need a timing device that takes into account how long the actual loop code executes. procedure TMainForm.OnIdleHandler(Sender: TObject; var Done: Boolean); const LOOP_TIME = 33; var start_time: DWORD; begin // Get loop start time start_time := GetTickCount(); MovePlayer; MoveEnemies; CheckCollisions; ClearScreen; DrawPlayer; DrawEnemies; // Wait until LOOP_TIME while(GetTickCount() - start_time end; Thanks to the above timing code and GetTickCount() we've got a game loop that is working a lot better than using the TTimer to execute the code.