Wave's~ BlitzMax Tutorial for NG~ November, 2015 ~ Version 11
Beginners guide to BlitzMax 

Refreshrate and Delta Time
FPS, Frames per Second is the speed at which your game updates. By default BlitzMax tries to update at the monitors refreshrate. In the Graphics command: Graphics Width , Height ,Depth, Refreshrate. You can specify a refreshrate which BlitzMax will try to follow. If you have a simple game like pong and play it on a very fast computer without any limitation to the refreshrate, that game would be so fast you wouldn't even see the ball. If you try to play a game on a slow system which gives you a refreshrate below the one specified your game will run slow, that's your games minimum requirements.

Put this type into any graphics code:
DrawText "Your FPS: "+FPS.Calc(),10,10 'This goes in main-loop
' FPS_Counter <> Runs and displays the FPS
' --------------------------------------------
Type FPS
  Global Counter, Time, TFPS
  Function Calc%()
    Counter:+1
    If Time < MilliSecs()
      TFPS = Counter
' <-Frames/Sec
      Time = MilliSecs() + 1000 'Update
      Counter = 0
    EndIf
    Return TFPS
  End Function
End Type
' -------------------------------------------
You can run at maximum refreshrate (set it free) and with the use of timing control your logic so it stays at the speed specified by you. In this way no matter what system that runs the game it will run with the same speed; Object A will travel to B in the same time. The object will not slow down but with severe lag the object will warp instead. Once you have specified an objects speed in pixels/sec it will always follow that speed no matter the FPS. But to counter, why would you want lag before slowdown? Multiplayer! In multiplayer each client has to run the game at the same speed. After I learnt how delta timing works I would never choose not to use it, unless we're talking about a very small game. Is deltatiming complicated? The answer is no, but it does require you to add a couple of lines of code to your game. If you add delta time you'll also be able to easily change the game speed while keeping the FPS constant which can be good sometimes.
Here follows the Tank example again, this time with DeltaTime. Try to pretend those squares are tanks.
Strict
Global Number_of_Tanks = 50 'How many tanks to create?
Const RefreshRate = 85 'Hz = FPS
'Const RefreshRate = NOSYNC 'Try this also
'Try to change the Refreshrate to 5,85,300
'This simulation should run at the same speed because
'of delta-timing. At what framerate does it lag at which
'is it smooth?
 
Type MoveObject
  Field X#,Y#
  Field Dir%
  Global DeltaTime:Float
  Global TimeDelay:Int ' Millisecs() returns int
  Function UpdateDeltaTime()
    DeltaTime = ( MilliSecs()- TimeDelay )*0.001 'Delta Timer
    TimeDelay = MilliSecs()
  End Function
End Type
 
Type Tank Extends MoveObject
  'Override the Speed Field in MoveObject
  Field Speed# = 400/1 ' Pixels / Seconds
  Field Size%=5
  Global TankNumber=0 'The current number of tanks
  Global TankList:TList
 
  'Draw draws a rect at the tank's X,Y
  Method Draw()
    DrawRect X,Y,Size,Size
  End Method
 
  'Go update the tank's movement
  Method Go()
    X:+Speed*Cos(Dir)*DeltaTime
    Y:+Speed*Sin(Dir)*DeltaTime
  End Method
 
  'Sets the starting values of the Tank
  Method SetupNew()
    Dir = Rand(0,360)
    X = (GraphicsWidth()/2)
    Y = (
GraphicsHeight()/2)
    Speed:*Rnd(0.1,1)
  End Method
 
  'This function Creates a new tank
  Function Create()
    'Create a List if none exists
    If Not TankList TankList = CreateList()
    Local NewTank:Tank = New Tank
    NewTank.SetupNew()
    TankList.AddLast( NewTank )
    TankNumber:+1
  End Function
End Type
 
Graphics 800,600,32,Refreshrate
' Create a bunch of new Tanks
For Local Nr = 1 To Number_of_Tanks
  Tank.Create()
Next
Delay 500
Tank.TimeDelay=MilliSecs()
While Not KeyDown(Key_Escape)
  Cls
  DrawText "Your FPS: "+FPS.Calc(),20,40
 
  MoveObject.UpdateDeltaTime() 'Update for all MoveObjects
 
  For Local T:Tank = EachIn Tank.TankList
    T.Draw
    DrawText "Number of Tanks : "+Tank.TankNumber,20,20
    T.Go 'update
  Next
  Flip
Wend
 
' FPS_Counter <> Runs And displays the FPS
'-------------------------------------------
Type FPS
  Global Counter, Time, TFPS
  Function Calc%()
    Counter:+1
    If Time < MilliSecs()
      TFPS = Counter ' <-Frames/Sec
      Time = MilliSecs() + 1000 ' Update
      Counter = 0
    End If
    Return TFPS
  End Function
EndType
' -------------------------------------------

When you want to add DeltaTime you can follow these steps:
 
1. Add these lines to your main loop.
DeltaTime# = ( MilliSecs()- TimeDelay )*0.001 ' Delta Timer
TimeDelay = MilliSecs()

Make sure that DeltaTime and TimeDelay are Globals so that you can use them in your functions and methods. I did it the OO-way in my Tank Example, but feel free to just paste this into your mainloop, does the same. Do you wonder why I multiply DeltaTime with 0.001? This is because millisecs() measures the time in milliseconds, 1000ms is one second. You probably want to measure your speed in seconds. That is pixels / seconds instead of pixels / milliseconds, that's why you divide DeltaTime with 1000 or multiply it with 0.001. Also make sure DeltaTime is a Float or Double! And that TimeDelay is an int.

2. To all variables that change over time, that is Speed, Acceleration, Shield generation, Energy Recharge.
Multiply them with DeltaTime.
X:+Speed*Cos(Dir)*DeltaTime
Y:+Speed*Sin(Dir)*DeltaTime
Sheild:+ SheildRechargeRate*DeltaTime

Make these variables are floats or doubles.
 
3. Redefine your speed. When using deltatime your speed is measured in pixels/second. This means that if you have a resolution of 800x600 and you want to travel the screenwidth in 3 seconds. Your speed would be = 800/3, 800 pixels in 3 seconds. That speed will be the same no matter the frame rate.
 
Here is my Delta-Type. It will help you with delta time. No excuse not to use it now =)
' _____________________________________________________
' ------------------------------------------------------
Type Delta
  ' D E L T A T I M E
  ' -----------------------------------------------------
  ' This type is Fully global. Which means you'll always
  ' refere to it as Delta.Start() , Delta.Time(),
  ' Delta.Update()
  '
  ' You shouldn't create instances of this type!
  ' DeltaTime is the same for all your objects!
  '
  Global DeltaTime#
  Global TimeDelay%
  ' Do this before your main loop
  ' If you don't there will be a jump in deltatime
  ' where it is very big until it cools down
  ' If anything is moving under that time it would get speeds
  ' well above 100000. So put this line before your main-loop
  Function Start()
    TimeDelay = MilliSecs()
  End Function
 
  ' Everytime where you want to get the deltatime
  ' call this: Delta.Time
  ' You should add this to every place which
  ' adds to your position/speed/acceleration
  ' But not to everything that adds
  '
  ' The basic rule is to add deltatime to all
  ' things which get added to every frame (over time)
  ' because this means they will get huge if
  ' you don't use delta.
  ' Like Speed:+ 10*Delta.Time
  Function Time#()
    Return DeltaTime#
  End Function
 
  ' Put this once in your main loop
  ' it calculates the current deltatime
  ' depending on your framerate or more exact
  ' the time between each/the last frame.
  Function Update()
    ' _____________________________________________________
    ' Purpose: Calculates DeltaTime , put it in mainloop
    ' ----------------------------------------------------
    DeltaTime = ( MilliSecs() - TimeDelay )*0.001
    TimeDelay = MilliSecs()

 
  End Function
End Type
'_____________________________________________________
'------------------------------------------------------
 
To Index | Next Page page 18