Deutsche
German translation
Français
French translation


Frame limiter (a.k.a. Delta-time) & Frames per second (FPS) calculator

Show Index

This bit of code performs two functions for you at the same time.

First, it calculates the FPS that your program is running at (by averaging the time that the last 5 frames took).

Second, it helps you to keep your game speed constant on ALL machines by providing you with two variables (SpeedFactor# or TimeElapsed#)  that you can use to multiply with all of your time-dependent game functions (such as player movement).  This feature helps keep your games running smoothly or fluidly (especially in scrolling type games).

 

To use, first place the following code in the beginning of your program:

Global Debug = True

Type FrameRate
  Field TargetFPS#
  Field SpeedFactor#
  Field TimeElapsed#
  Field FPS#
  Field FPS2#
  Field FPS3#
  Field FPS4#
  Field FPS5#
  Field CurrentTicks
  Field FrameDelay
End Type

Global FL.FrameRate = New FrameRate

;initialize frame limiter
FL\TargetFPS# = 60	;set this to whatever FPS your code is based on
FL\FrameDelay = MilliSecs()

Next, place the following code inside of your game loop: (this is where the calculations are performed)

;Set Speed Factor
FL\CurrentTicks = MilliSecs()
FL\SpeedFactor# = (FL\CurrentTicks - FL\FrameDelay) / (1000.0 / FL\TargetFPS#)
If FL\SpeedFactor# <= 0 Then FL\SpeedFactor# = 0.00000000001
FL\TimeElapsed# = (FL\CurrentTicks - FL\FrameDelay) / 1000.0
If Debug
  FL\FPS# = (FL\FPS2# + FL\FPS3# + FL\FPS4# + FL\FPS5# + FL\TargetFPS# / FL\SpeedFactor#) / 5
  FL\FPS5# = FL\FPS4# : FL\FPS4# = FL\FPS3# : FL\FPS3# = FL\FPS2# : FL\FPS2# = FL\FPS#
EndIf
FL\FrameDelay = FL\CurrentTicks

Lastly, use the following methods to make use of the above code.

 

To display a frames per second (FPS) counter

Simply add something similar to the following code somewhere in your game loop:

;example FPS display
If Debug
 Text 0, 0, "FPS: " + Int(FL\FPS#)
EndIf

To make your game objects move equally on all machines

To make use of the frame limiting functionality, you have to use either the SpeedFactor# variable or the TimeElapsed# variable.  Which one you need to use depends on the type of game you are writing.  SpeedFactor# contains a percentage of the last frame.  TimeElapsed# contains a percentage of the last second.

If your game has objects that move a certain distance every FRAME then you will want to use the SpeedFactor# variable.

If your game has objects that move a certain distance every SECOND then you will want to use the TimeElapsed# variable.

 

Use of the SpeedFactor# variable:

Let's say you are writing a side-scrolling platform type game.  While the player presses the right arrow key, the players sprite moves 4 pixels over every frame.   Usually you would program this as:

If KeyDown(205)
 PlayerX = PlayerX + 4
EndIf

To achieve smooth scrolling on all computers, you would modify the above code to read as follows:

If KeyDown(205)
 PlayerX = PlayerX + 4.0 * FL\SpeedFactor#
EndIf

This will cause the players sprite to move 4 pixels over +/- a difference determined by the speedfactor.
If, for instance, the last frame took longer than normal (as determined by the TargetFPS# variable) then SpeedFactor# will equal a number greater than 1.0 (let's say 1.25 for instance).  4x1.25=5 so the players sprite will move 5 pixels this frame instead of 4 to make up for the extra time the last frame took.

Click here to see an example of the advantage of using Delta-timing vs. using a Timer.

 

Use of the TimeElapsed# variable:

Let's say that you are writing a car racing simulator.  Since you want the car to move based on real-world time, you want to use the TimeElapsed# variable.

In your game, to calculate the new velocity of the car every frame, you use the formula:

newvelocity = oldvelocity + (time * acceleration)

velocity is in meters per second (m/s)
time is in seconds (s)
acceleration is in meters per second per second (m/s^2)

Quite simply, all we have to do is substitute the TimeElapsed# variable in place of the time (since TimeElapsed# equals how long it's been (in seconds) since the last frame)

newvel# = oldvel# + (FL\TimeElapsed# * accel#)

Now the car will change it's velocity based on ACTUAL time that has passed since the last frame.

 

If you've reached this page and there's no index on the left, Click here to show the Index Page