ATTENTION READERS! Lucky's VB Gaming Site
is no longer active. For updated game programming information
and tutorials, please visit The
Game Programming Wiki!
Time-Based Modeling
EAT.. MY.. JUSTICE! Anyone ever watch "The Tick"? No? :(
Anyway! I do have a reason for talking about "justice".. do
you think it's fair that someone with a Pentium-133 should get
the same frame rates in a game as someone with a PIII-800? I
mean, c'mon, the person with the PIII deserves a little extra
somethin' for all that money they've spent! Putting a frame
cap on your game is NOT the only method available to you. Let
the computer crank out as many FPS as it can by using
"Time-Based Modeling"!
The key to this method is determining the time elapsed
since the last frame was displayed. You then use this value in
all of your game calculations, effectively giving weight
according to the frame rate attained. Also, you'll have to
describe your game's "speed" values in units per second (ie.
pixels per second) rather than units per frame.
Lets give a simple example to make this perfectly clear.
Imagine Mario is running to the right at 20 pixels/second. If
our elapsed time since the last frame was 0.05 seconds (50
milliseconds), then Mario will have travelled 1 pixel
(20pixels/second * 0.05seconds). If our elapsed time was 200
milliseconds (a REALLY slow computer) then Mario will have
travelled 4 pixels. You see, the number of pixels PER FRAME
will vary, but the total number of pixels PER SECOND will
always remain constant, no matter how slow the computer!
Dim mlngTimer as Long
Dim mlngElapsed as Long
Dim mlngFrameTimer as Long
Dim mintFPSCounter as Integer
Dim mintFPS as Integer
Private Sub Timer()
mlngElapsed = GetTickCount() - mlngTimer
mlngTimer = GetTickCount()
If GetTickCount() - mlngFrameTimer >= 1000 Then
mlngFrameTimer = GetTickCount()
mintFPS = mintFPSCounter
mintFPSCounter = 0
Else
mintFPSCounter = mintFPSCounter + 1
End If
End Sub
Call this little subroutine from within a "Do-While" loop
(your main render loop) and it'll place the elapsed time in
the variable mlngElapsed. It'll also fill the variable
mintFPS with the number of frames displayed last
second.
After calling this Timer subroutine, perform your
physics calculations using the value of mlngElapsed.
Using our Mario example:
msngMarioX = msngMarioX + mlngElapsed * msngMarioSpeed
So, if Mario was at pixel zero, and 200 milliseconds
elapsed while he was moving with a speed of 0.02
pixels/millisecond we'd get:
msngMarioX = (0) + (200) * (0.02)
Which equals 4 pixels. Easy-shmeasy. Using this method your
game will look as good as it can on any given computer; no CPU
cycles are wasted! Also, if you're considering a network game
I'd highly recommend this architecture. The inescapable
latency of network games can easily be accommodated since
delay handling is already built into the physics routines!
Download my sample
source code if you're still a little foggy on this whole
concept.
|