Mega Code Archive

 
Categories / Delphi / Examples
 

Real time movement in games

Title: Real time movement in games Question: Why waste processing time while waiting for a delay to have passed. Move your sprite as much as possible for smoother animation. Answer: In this example I'm moving the application icon from left to right with a certain speed (300 pixels per second), WITHOUT a timer. I only use a loop, and check with each loop how much time has passed and thus how much I should move. To get the time, I use GetTickCount, which should return the number of milli seconds since booting. The following code will show that it doesn't change every milli second. var s: cardinal begin s := GetTickCount; repeat Memo1.Lines.Add( IntToStr( GetTickCount ) ); until s end; If you look at the result in the memo, you'll see that it produces times the same number, and then suddenly increases with 10 instead of 1. (This may vary on other configurations.) So unfortunately we won't reach a frame rate higher than 100.. Good enough for me. :-) Back to the sample. I chose a speed of 300 Pixels per second, and I determined how many pixels I should move in one tick (one milli second). In a loop (the Game Main loop) I calculate how much ticks have passed, and multiply this with PixelsPerTick value. Now I know how much to move. Place the code below in a buttons OnClick event, and see what happens. procedure TForm1.Button1Click(Sender: TObject); const PIXELSPERSECOND = 300; var x : single; PixelsPerTick: single; StartTick, OldTick, CurTick, TickDif: Cardinal; Frames: integer; begin PixelsPerTick := (PIXELSPERSECOND / 1000); Refresh; // Clear previous drawing Frames := 0; x := 0; // Set initial position StartTick := GetTickCount; CurTick := StartTick; repeat Application.ProcessMessages; // Make application react to (user) input OldTick := CurTick; // Time at last frame CurTick := GetTickCount; // Current time TickDif := CurTick - OldTick; // Time delta if TickDif 0 then // At least 1 milli second has passed since last frame begin inc( Frames ); // Just a counter for statistics x := x + (PixelsPerTick * TickDif); // move sprite Canvas.Draw( Round(x), 15, Application.Icon ); // Draw sprite end; until x (Width - 32); // We've moved across the window? // Show some statistics ShowMessage( Format ( '%d frames in %f seconds. Moved %d pixels. %f frames per second', [Frames, (CurTick-StartTick)/1000, Round( x ), (Frames/((CurTick-StartTick)/1000)) ] ) ); end;