Games - programando em realtime
|Top Previous Next|
Why waste processing time while waiting for a delay to have passed.
Move your sprite as much as possible for smoother animation.
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
s := GetTickCount;
Memo1.Lines.Add( IntToStr( GetTickCount ) );
until s < (GetTickCount-1000);
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);
PIXELSPERSECOND = 300;
x, PixelsPerTick: single;
StartTick, OldTick, CurTick, TickDif: Cardinal;
PixelsPerTick := (PIXELSPERSECOND / 1000);
Refresh; // Clear previous drawing
Frames := 0;
x := 0; // Set initial position
Canvas.Pen.Color := Color;
Canvas.Brush.Color := Color;
StartTick := GetTickCount;
CurTick := StartTick;
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
Canvas.Rectangle( Round(X), 15, Round(X) + 32, 35+15); // Junior: para apagar o antigo
inc( Frames ); // Just a counter for statistics
x := x + (PixelsPerTick * TickDif); // move sprite
Canvas.Draw( Round(x), 15, Application.Icon ); // Draw sprite
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)) ] ) );