September 23, 2018, 12:21:09 PM

Author Topic: [bb] Speed of the turns/moves/animations automatically adjusted to appear constant whatever the FPS by RemiD [ 1+ years ago ]  (Read 495 times)

Offline BlitzBot

  • Jr. Member
  • **
  • Posts: 1
Title : Speed of the turns/moves/animations automatically adjusted to appear constant whatever the FPS
Author : RemiD
Posted : 1+ years ago

Description : This allows your program to run at the same speed whatever the FPS, whatever is drawn on screen, whatever the computer hardware

Code :
Code: BlitzBasic
  1. ;Speed of the turns/moves/animations automatically adjusted to appear constant whatever the FPS
  2. ;
  3. ;This code shows a way to have an automatic adjustment of the speed of the turns/moves/animations
  4. ;so that the program appears to run at the same speed, whatever the FPS, whatever is drawn on screen, whatever the hardware of the computer/graphics card.
  5. ;The variable SC# must be applied to all turns/moves/animations. See the example.
  6. ;I have tested this code on several computers with different hardwares and os and it seems to work as expected.
  7. ;There may be inaccuracies if there is less than 10fps but overall it works well.
  8.  
  9. Graphics3D(800,600,32,2)    
  10.    
  11. HidePointer()  
  12.  
  13. SeedRnd(MilliSecs())
  14.    
  15. Origine = CreateCube()
  16. ScaleMesh(Origine,0.1/2,100,0.1/2)
  17. EntityColor(Origine,125,000,000)
  18. EntityAlpha(Origine,0.5)
  19. EntityFX(Origine,1)
  20. PositionEntity(Origine,0,0,0)
  21.  
  22. Target = CreateCube()
  23. ScaleMesh(Target,0.1/2,100,0.1/2)
  24. EntityColor(Target,250,000,000)
  25. EntityAlpha(Target,0.5)
  26. EntityFX(Target,1)
  27. PositionEntity(Target,0,0,128)
  28.  
  29. GroundMesh = CreatePlane()    
  30. PositionEntity(GroundMesh,0,0,0)    
  31. EntityColor(GroundMesh,050,050,050)        
  32.      
  33. Camera = CreateCamera()  
  34. CameraRange(Camera,0.1,1000)
  35. CameraClsColor(Camera,063,125,250)  
  36. PositionEntity(Camera,0,0,0)  
  37.  
  38. CharacterMesh = CreateCube()
  39. ScaleMesh(CharacterMesh,0.5/2,1.7/2,0.25/2)
  40. PositionMesh(CharacterMesh,0,1.7/2,0)
  41. HideEntity(CharacterMesh)
  42.  
  43. Global PlayerFeet = CreatePivot()
  44. Global PlayerEyes = CreatePivot()
  45. MoveEntity(PlayerEyes,0,1.6,0.1+0.1)
  46. EntityParent(PlayerEyes,PlayerFeet,True)
  47. Global PlayerMesh = CopyMesh(CharacterMesh)
  48. EntityColor(PlayerMesh,000,000,250)
  49. EntityParent(PlayerMesh,PlayerFeet,True)
  50.  
  51. PositionEntity(Camera,EntityX(PlayerEyes,True),EntityY(PlayerEyes,True),EntityZ(PlayerEyes,True))
  52. RotateEntity(Camera,EntityPitch(PlayerEyes,True),EntityYaw(PlayerEyes,True),EntityRoll(PlayerEyes,True))
  53. MoveEntity(Camera,0,0,-1.5)
  54. EntityParent(Camera,PlayerEyes,True)
  55. TurnEntity(PlayerEyes,22.5,0,0)
  56.  
  57. Global BotsCount% = 0  
  58. Dim BotFeet(10000)
  59. Dim BotMesh(10000)
  60.  
  61. For i% = 1 To 1000 ;change this value to 1 or 10 or 100 or 1000 or more to see how the speed of the turns/moves are automatically adjusted so that it appears to run at the same speed whatever the FPS, whatever is drawn on screen.
  62.  BotsCount = BotsCount + 1
  63.  BId% = BotsCount
  64.  BotFeet(BId) = CreatePivot()
  65.  BotMesh(BId) = CopyMesh(CharacterMesh)
  66.  EntityColor(BotMesh(BId),Rand(025,250),Rand(025,250),Rand(025,250))
  67.  EntityParent(BotMesh(BId),BotFeet(BId),True)
  68.  PositionEntity(BotFeet(BId),Rnd(-30,30),0,Rnd(10,90))
  69.  RotateEntity(BotFeet(BId),0,Rnd(-180,180),0)
  70. Next
  71.  
  72. SLight = CreateLight(1)
  73. LightColor(SLight,255,255,255)  
  74. PositionEntity(SLight,-1000,1000,-1000)
  75. RotateEntity(SLight,45,-45,0)
  76.  
  77. AmbientLight(050,050,050)
  78.  
  79. MillisecOld% = MilliSecs()
  80. MillisecCur% = MilliSecs()
  81. SecsCount% = 0
  82. FramesCount% = 0
  83. FramesTotalCount% = 0
  84. FramesPerSecond% = 0
  85. Global SC# = 1.0  
  86.    
  87. While(KeyDown(1)<>1)    
  88.  
  89.  MainLoopStart% = MilliSecs()      
  90.          
  91.  UpdateBots()
  92.  
  93.  UpdatePlayer()
  94.          
  95.  If( EntityZ(PlayerFeet) >= EntityZ(Target) )
  96.   ClsColor(000,000,000)
  97.   Cls()
  98.   Locate(0,0)
  99.   Print("Average FramesPerSecond (FPS) = "+FramesTotalCount/SecsCount)
  100.   Print("Seconds passed during the travel = "+SecsCount)
  101.   FlushKeys()
  102.   WaitKey()
  103.   Goto LineExitGame
  104.  EndIf
  105.          
  106.  SetBuffer(BackBuffer())
  107.  
  108.  RenderWorld()    
  109.                  
  110.  MillisecCur = MilliSecs()
  111.  If(MillisecCur < MillisecOld + 1000)
  112.   FramesCount = FramesCount + 1
  113.  ElseIf(MillisecCur >= MillisecOld + 1000)
  114.   FramesPerSecond = FramesCount
  115.   FramesTotalCount = FramesTotalCount + FramesCount
  116.   FramesCount = 0  
  117.   SecsCount = SecsCount + 1
  118.   MillisecOld = MillisecCur                          
  119.  EndIf
  120.                        
  121.  Text(0,0,"Triangles = "+TrisRendered())  
  122.  Text(0,20,"MainLoopTime = "+MainLoopTime)  
  123.  Text(0,40,"FramesCount = "+FramesCount)
  124.  Text(0,60,"FramesPerSecond (FPS) = "+FramesPerSecond)
  125.  Text(0,80,"FramesTotalCount = "+FramesTotalCount)    
  126.  Text(0,100,"SC = "+SC)
  127.  Text(0,120,"SecsCount = "+SecsCount)            
  128.  Text(0,140,"See how the speed of the turns/moves are automatically adjusted so that ")
  129.  Text(0,160,"it appears to run at the same speed, whatever the FPS, whatever is drawn on screen.")
  130.          
  131.  Flip(True)
  132.  
  133.  MainLoopTime% = MilliSecs() - MainLoopStart
  134.  If(MainLoopTime < 1)
  135.   MainLoopTime = 1
  136.  EndIf   
  137.    
  138.  SC = Float(30) / 1000 * MainLoopTime  
  139.        
  140. Wend
  141. .LineExitGame
  142.  
  143. EndGraphics()
  144.  
  145. End()
  146.  
  147. Function UpdatePlayer()
  148.  MoveEntity(PlayerFeet,0,0,0.2*SC)
  149. End Function
  150.  
  151. Function UpdateBots()
  152.  For BId% = 1 To BotsCount
  153.   TurnEntity(BotFeet(BId),0,2.0*SC,0)
  154.   MoveEntity(BotFeet(BId),0,0,0.2*SC)
  155.  Next
  156. End Function


Comments :


Imperium(Posted 4 months ago)

 Amazing! thanks!


Offline RemiD

  • Hero Member
  • *****
  • Posts: 609
updated code example, simplified, clarified, with a scene made of meshes and images (to really see the impact on the FPS, but which does not impact the speed of the turns/moves/animations)
26/01/2018
Code: [Select]
;Speed of the turns/moves/animations automatically adjusted to appear constant whatever the FPS
;
;This code shows a way to have an automatic adjustment of the speed of the turns/moves/animations
;so that the program appears to run at the same speed, whatever the FPS, whatever is drawn on screen, whatever the hardware of the computer/graphics card.
;The variable SpeedCoeff# must be applied to all turns/moves/animations. See the example.
;I have tested this code on several computers with different hardwares and os and it seems to work as expected.
;There may be inaccuracies if there is less than 10fps but overall it works well.

Global ProgramState%
Const CStart% = 1
Const CUpdate% = 2
Const CEnd% = 3

ProgramState = CStart

Graphics3D(800,600,32,2)     
   
HidePointer() 

SeedRnd(MilliSecs())

Global Origine = CreateCube()
ScaleMesh(Origine,0.1/2,0.1/2,0.1/2)
EntityColor(Origine,125,000,125)
EntityAlpha(Origine,0.5)
EntityFX(Origine,1)
PositionEntity(Origine,0,0,0,True)

Global Target = CreateCube()
ScaleMesh(Target,0.1/2,100.0,0.1/2)
EntityColor(Target,250,000,250)
EntityAlpha(Target,0.5)
EntityFX(Target,1)
PositionEntity(Target,0,0,128.0,True)

GroundMesh = CreatePlane()     
EntityColor(GroundMesh,125,125,125)
PositionEntity(GroundMesh,0,0,0)           
     
Global Camera = CreateCamera()   
CameraRange(Camera,0.1,1000)
CameraViewport(Camera,0,0,GraphicsWidth(),GraphicsHeight())     
CameraClsColor(Camera,000,000,000)

XCharacterMesh = CreateCube()
ScaleMesh(XCharacterMesh,0.5/2,1.75/2,0.25/2)
PositionMesh(XCharacterMesh,0,1.75/2,0)
HideEntity(XCharacterMesh)

Global PlayerFeet = CreatePivot()
Global PlayerEyes = CreatePivot()
MoveEntity(PlayerEyes,0,1.65,0)
EntityParent(PlayerEyes,PlayerFeet,True)
Global PlayerMesh = CopyEntity(XCharacterMesh)
EntityColor(PlayerMesh,000,000,250)
EntityParent(PlayerMesh,PlayerFeet,True)

Global BotsCount% = 0
Dim BotFeet(10000)
Dim BotMesh(10000)

For n% = 1 To 2000 ;change this value to 1 or 10 or 100 or 1000 or more
 BotsCount = BotsCount + 1
 I% = BotsCount
 BotFeet(I) = CreatePivot()
 BotMesh(I) = CopyEntity(XCharacterMesh)
 EntityColor(BotMesh(I),Rand(025,250),Rand(025,250),Rand(025,250))
 EntityParent(BotMesh(I),BotFeet(I),True)
 PositionEntity(BotFeet(I),Rnd(-30,30),0,Rnd(10,90),True)
 RotateEntity(BotFeet(I),0,Rnd(-180,180),0,True)
Next

DLight = CreateLight(1)
LightColor(DLight,255,255,255) 
PositionEntity(DLight,0,1000,-1000,True)
RotateEntity(DLight,45,0,0,True)
 
AmbientLight(064,064,064)

TurnEntity(PlayerEyes,22.5,0,0)

;to count the millitime it takes for player to from the start point to the target point
Global TravelMilliStart% = MilliSecs()
Global TravelMilliTime%

;to count the millitime a mainloop takes
Global MainLoopMilliStart%
Global MainLoopMilliTime%

;to lock the FPS at 30fps maximum
Global MainLoopTimer = CreateTimer(30)

;to count the number of frames per second
Global FPS%

;the value to apply to all turns/moves/animations so that the speed of the turns/moves/animations appear constant whatever the FPS, whetever is drawn on the screen
Global SpeedCoeff# = 1.0   
   
ProgramState = CUpdate

Main()

EndGraphics()

End()

Function Main()

 Repeat   
 
  MainLoopMilliStart = MilliSecs()     
         
  UpdateBots()

  UpdatePlayer()

  If( EntityZ(PlayerFeet,True) >= EntityZ(Target,True) )
   ClsColor(000,000,000) : Cls()
   Locate(0,0)
   Print("Total time passed during the travel = "+Int(Float(TravelMilliTime)/1000)+"seconds")
   FlushKeys()
   WaitKey()
   ProgramState = CEnd
 EndIf

 TravelMilliTime = MilliSecs() - TravelMilliStart

 ;position/rotate the camera before the rendering of the scene
 PositionEntity(Camera,EntityX(PlayerEyes,True),EntityY(PlayerEyes,True),EntityZ(PlayerEyes,True))
 RotateEntity(Camera,EntityPitch(PlayerEyes,True),EntityYaw(PlayerEyes,True),EntityRoll(PlayerEyes,True))
 MoveEntity(Camera,0,0,-1.5)

 CameraViewport(Camera,0,0,GraphicsWidth(),GraphicsHeight())     
 CameraClsColor(Camera,000,000,000)
 SetBuffer(BackBuffer())

 RenderWorld()     

 For n% = 1 To 10 Step 1 ;change this value to 1 or 10 or 100 or more
  PWidth% = Rand(25,100) : PHeight% = Rand(16*1,16*10)
  PX% = Rand(0+1,GraphicsWidth()-PWidth-1) : PY% = Rand(0+1,GraphicsHeight()-PHeight-1)
  Color(Rand(025,255),Rand(025,255),Rand(025,255)) : Rect(PX,PY,PWidth,PHeight,True)
 Next
   
 Color(255,255,255)      
 Text(0,0,"Triangles = "+TrisRendered())   
 Text(0,16,"MainLoopMilliTime = "+MainLoopMilliTime)   
 Text(0,32,"FPS = "+FPS)   
 Text(0,48,"SpeedCoeff = "+SpeedCoeff)
 Text(0,64,"Current time of the travel = "+Int(Float(TravelMilliTime)/1000)+"seconds")   
 Text(0,80,"See how the speed of the turns/moves/animations are automatically adjusted so that ")
 Text(0,96,"it appears to run at the same speed, whatever the FPS, whatever is drawn on screen.")

 ;Flip(true)
 WaitTimer(MainLoopTimer)
 VWait():Flip(False)
 
 MainLoopMilliTime = MilliSecs() - MainLoopMilliStart
 If(MainLoopMilliTime < 1)
  MainLoopMilliTime = 1
 EndIf  
   
 SpeedCoeff = Float(30) / 1000 * MainLoopMilliTime

 FPS% = 1000.0/MainLoopMilliTime

 Until( KeyDown(1)=1 Or ProgramState = CEnd )

End Function
 
Function UpdatePlayer()

 MoveEntity(PlayerFeet,0,0,0.2*SpeedCoeff)

End Function
 
Function UpdateBots()

 For I% = 1 To BotsCount

  TurnEntity(BotFeet(I),0,2.0*SpeedCoeff,0)
  MoveEntity(BotFeet(I),0,0,0.2*SpeedCoeff)

 Next

End Function