VB:Tutorials:Time Based Modelling

From GPWiki
Jump to: navigation, search

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 Modelling!

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 (or fast) the computer!

Private Declare Function GetTickCount Lib "kernel32" () As Long
 
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 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 the time based modelling sample source code if you're still a little foggy on this whole concept.