So I wanted to implement delta-time (and global/individual time scale); thought it was easy... I picked up pieces of code here and there, but I'm at the point where I don't fully understand the code, even though it's not (yet) a complete fail.
Here is the code:
Code: Select all
Enumeration
#Cursor
EndEnumeration
Structure _fps
targetFps.f
fps.f
ticksPerSecond.i
currentTicks.i
frameDelay.i
frameRate_real.i
frameRate_internal.i
frameStep.f
EndStructure
Structure _world
delta.f
timeScale.f
EndStructure
Structure _object
sprite.i
timeScale.f
speed.f
x.f
y.f
destX.f
destY.f
EndStructure
Structure _xy
x.f
y.f
EndStructure
; ------------------------
Global world._world, object1._object
Global fps._fps
Procedure DrawCursor()
CreateSprite(#Cursor, 2, 2, #PB_Sprite_AlphaBlending)
EndProcedure
Procedure DrawObject(*object._object)
*object\sprite = CreateSprite(#PB_Any, 4, 4, #PB_Sprite_AlphaBlending)
EndProcedure
Procedure Init()
InitSprite() : InitKeyboard() : InitMouse()
fps\frameRate_real = 60
fps\frameRate_internal = 60
fps\frameStep = fps\frameRate_real * 0.1
EndProcedure
; ------------------------
Procedure InitFPSLimit(target.f)
fps\targetFps = target
fps\ticksPerSecond = 1000
fps\frameDelay = GetTickCount_()
EndProcedure
Procedure SetSpeedFactor()
fps\currentTicks = GetTickCount_()
world\delta = (fps\currentTicks - fps\frameDelay) / (fps\ticksPerSecond / fps\targetFps)
If world\delta <= 0
world\delta = fps\targetFps * 0.001
EndIf
fps\fps = fps\targetFps / world\delta
fps\frameDelay = fps\currentTicks
EndProcedure
Procedure.f GetDistance(x1.i, y1.i, x2.i, y2.i)
Define dx.f = x1 - x2
Define dy.f = y1 - y2
Define dist.f = Sqr(dx*dx + dy*dy)
If dist < 0
dist * -1
EndIf
ProcedureReturn dist
EndProcedure
Procedure MoveObject(*object._object, destX.i, destY.i)
Define direction._xy, distance.f, norm.f
*object\destX = destX
*object\destY = destY
direction\x = *object\destX - *object\x
direction\y = *object\destY - *object\y
norm.f = Sqr(Pow(direction\x, 2) + Pow(direction\y, 2))
If norm
direction\x / norm
direction\y / norm
EndIf
distance = GetDistance(*object\x, *object\y, *object\destX, *object\destY)
If distance < *object\speed
;*object\x + direction\x * distance
;*object\y + direction\y * distance
;*object\x = *object\destX
;*object\y = *object\destY
Else
*object\x + (direction\x * *object\speed) * world\delta
*object\y + (direction\y * *object\speed) * world\delta
EndIf
EndProcedure
Procedure InitObject(*object._object)
DrawObject(*object)
*object\speed = 5
*object\timeScale = 1
EndProcedure
; ------------------------
Init()
OpenWindow(0, 0, 0, 640, 640, "", #PB_Window_ScreenCentered)
OpenWindowedScreen(WindowID(0), 0, 0, 640, 640, 0, 0, 0, #PB_Screen_NoSynchronization)
DrawCursor()
InitObject(@object1)
SetFrameRate(fps\frameRate_real)
InitFPSLimit(fps\frameRate_internal / fps\frameStep)
Repeat
While WindowEvent() : Wend
FlipBuffers()
ClearScreen(0)
ExamineKeyboard() : ExamineMouse()
SetSpeedFactor()
If MouseButton(#PB_MouseButton_Left)
MoveObject(@object1, MouseX(), MouseY())
EndIf
DisplayTransparentSprite(#Cursor, MouseX(), MouseY(), 255, #White)
DisplayTransparentSprite(object1\sprite, object1\x, object1\y, 255, RGB(0, 255, 0))
Delay(1)
Until KeyboardPushed(#PB_Key_Escape)