Hi guy's, I made a function that handles increasing and decreasing of values via timers. So say I wanted to move and object from point 'A' to point 'B', I could setup a timer and set how long it would take in seconds, when I want to start it I just return the timer to the object position, easy.
So the code and demo:
remstart
* Project: Timer Based Value Inc/Dec function
* ------------------------------------------------------------------------------------
* Created: 17/11/2008 15:22:42
* Author: Zak "Sasuke" Everett
* ------------------------------------------------------------------------------------
* Credit: Thank Guy's
* - tiresius, giving me a much better idea of how to handle this
* ------------------------------------------------------------------------------------
* log: date: time: author:
* 1 19/11/2008 N/A Sasuke
* Removed handles form initValTimer
remend
`Initialize are global timer and valTimer array
init_gTimer()
`Setup are are timers
myTimer1 = findFreeValTimer()
myTimer2 = findFreeValTimer()
`Setup a timer that will go from 0 to 10 in 5 seconds
initValTimer( myTimer1 , 0.0 , 10.0 , 5.0 )
`Setup a timer that will go from 10 to -10 in 5 seconds
initValTimer( myTimer2 , 10.0 , -10.0 , 5.0 )
`Main loop
do : update_gTimer() `Update are global timer before anything else
cls
`Time in seconds
time# = (g_Timer.oldTick - g_Timer.lastTick) / 1000.0
`Start are timers and return the current value
myValue1# = getValTimer( myTimer1 )
myValue2# = getValTimer( myTimer2 )
`debug
ts = text size()
text 0,0,"[Sasuke's Timer Based Inc/Dec]"
text 0,ts,"Time: "+str$(time#,2)
text 0,ts*3,"0 to 10 in 5 seconds: "+str$(myValue1#,2)
text 0,ts*4,"-10 to 10 in 5 seconds: "+str$(myValue2#,2)
sync
loop
`Good old UDT's
type udt_valTimer
init as boolean
fromVal as float
toVal as float
lastTick as float
duration as float
ended as boolean
endtype
type udt_gTimer
newTick as dword
oldTick as float
curTick as dword
lastTick as float
endtype
`Initialize are global timer and valTimer array
function init_gTimer()
global g_Timer as udt_gTimer
g_Timer.oldTick = timer()
g_Timer.lastTick = g_Timer.oldTick
global dim _valTimer() as udt_valTimer
endfunction
`Update are global timer
function update_gTimer()
g_Timer.newTick = timer()
g_Timer.curTick = g_Timer.newTick - g_Timer.oldTick
g_Timer.oldTick = g_Timer.newTick
endfunction
`Returns a new ValTimer
function findFreeValTimer()
array insert at bottom _valTimer()
out = array count(_valTimer())
endfunction out
`* Function: initValTimer
`* ------------------------------------------------------------------------------------
`* - Desc: Will set up a timer and it varible for later use
`* ------------------------------------------------------------------------------------
`* - index: the array index for _valTimer().
`* - fromVal: the value you want to start from.
`* - toVal: the value you want to get to.
`* - duration: The amount of time you want it to take in seconds
`* ------------------------------------------------------------------------------------
function initValTimer( index as integer , fromVal as float , toVal as float , duration as float )
_valTimer(index).init = 0
_valTimer(index).ended = 0
_valTimer(index).fromVal = fromVal
_valTimer(index).toVal = toVal
_valTimer(index).lastTick = 0.0
_valTimer(index).duration = duration
endfunction
`Reset the timer so it can be alter again by initValTimer()
function resetValTimer( index as integer )
_valTimer(index).init = 0
_valTimer(index).ended = 0
_valTimer(index).fromVal = 0.0
_valTimer(index).toVal = 0.0
_valTimer(index).lastTick = 0.0
_valTimer(index).duration = 0.0
endfunction
`Starts are timer and return the current value
function getValTimer( n as integer )
local time as float
local out as float
if _valTimer(n).ended > 0
out = _valTimer(n).toVal
exitfunction out
endif
if _valTimer(n).init < 1
_valTimer(n).lastTick = g_Timer.oldTick
_valTimer(n).init = 1
endif
time = (g_Timer.oldTick - _valTimer(n).lastTick ) / 1000.0
out = ((time * (_valTimer(n).toVal-_valTimer(n).fromVal)) / _valTimer(n).duration) + _valTimer(n).fromVal
if _valTimer(n).fromVal < _valTimer(n).toVal
if out >= _valTimer(n).toVal
out = _valTimer(n).toVal
_valTimer(n).ended = 1
exitfunction out
endif
else
if out <= _valTimer(n).toVal
out = _valTimer(n).toVal
_valTimer(n).ended = 1
exitfunction out
endif
endif
endfunction out
I also put together a little sprite demo to test how efficient this is and the results are amazing.
Here's the Cool Demo: Edit
cMYSPRITE_COUNT to increase/decrease the amount of sprites.
#constant cSYNCRATE_CAP 0
#constant cMYSPRITE_COUNT 64
#constant cSPRITE_SCALE 24 `need to be greater than 4
#constant cBITDUMP 1
initOnSync( cSYNCRATE_CAP )
initDisplay( 1024 , 768 , 32 , 0 , 0 )
init_gTimer()
type udt_valTimer
init as boolean
fromVal as float
toVal as float
lastTick as float
duration as float
ended as boolean
endtype
global dim _valTimer() as udt_valTimer
type udt_sprites
id as integer
img as integer
timerNumX as integer
timerNumY as integer
timerUpdateX as boolean
timerUpdateY as boolean
fadeTimerNum as integer
fadeTimerUpdate as boolean
fadeCur as float
fadeTo as float
alphaMin as integer
alphaMax as integer
fadeDuration as float
posX as float
posY as float
toX as float
toY as float
durationX as float
durationY as float
endtype
global dim _mySprite() as udt_sprites
for n = 0 to cMYSPRITE_COUNT-1
array insert at bottom _mySprite()
_mySprite().id = findFreeSprite()
_mySprite().img = findFreeImage()
_mySprite().timerNumX = findFreeValTimer()
_mySprite().timerNumY = findFreeValTimer()
_mySprite().timerUpdateX = 0
_mySprite().timerUpdateY = 0
_mySprite().fadeTimerNum = findFreeValTimer()
_mySprite().fadeTimerUpdate = 0
_mySprite().alphaMin = 0.0
_mySprite().alphaMax = 255.0
_mySprite().fadeCur = 0.0
_mySprite().fadeTo = 0.0
_mySprite().fadeDuration = 0.0
_mySprite().toX = rnd(screen width())
_mySprite().toY = rnd(screen height())
_mySprite().durationX = 0.0
_mySprite().durationY = 0.0
set current bitmap cBITDUMP
ink rgb(rnd(255),rnd(255),rnd(255)),0 : box 0,0,cSPRITE_SCALE,cSPRITE_SCALE
ink rgb(rnd(255),rnd(255),rnd(255)),0 : box 4,4,cSPRITE_SCALE-4,cSPRITE_SCALE-4
get image _mySprite().img,0,0,cSPRITE_SCALE,cSPRITE_SCALE,1
cls
set current bitmap 0
sprite _mySprite().id ,_mySprite().toX,_mySprite().toY,_mySprite().img
hide sprite _mySprite().id
next n
backdrop on : color backdrop 0
do : update_gTimer()
for n = 0 to array count(_mySprite())
if _mySprite(n).posX = _mySprite(n).toX then _mySprite(n).timerUpdateX = 0
if _mySprite(n).posY = _mySprite(n).toY then _mySprite(n).timerUpdateY = 0
if _mySprite(n).fadeCur = _mySprite(n).fadeTo then _mySprite(n).fadeTimerUpdate = 0
if _mySprite(n).timerUpdateX = 0
resetValTimer( _mySprite(n).timerNumX )
_mySprite(n).durationX = rnd(3.5)+0.5
_mySprite(n).toX = rnd(screen width())
if _mySprite(n).toX > (screen width()-cSPRITE_SCALE) then _mySprite(n).toX = screen width()-cSPRITE_SCALE
initValTimer( _mySprite(n).timerNumX , _mySprite(n).posX , _mySprite(n).toX , _mySprite(n).durationX )
inc _mySprite(n).timerUpdateX
endif
if _mySprite(n).timerUpdateY = 0
resetValTimer( _mySprite(n).timerNumY )
_mySprite(n).durationY = rnd(3.5)+0.5
_mySprite(n).toY = rnd(screen height())
if _mySprite(n).toY > (screen height()-cSPRITE_SCALE) then _mySprite(n).toY = screen height()-cSPRITE_SCALE
initValTimer( _mySprite(n).timerNumY , _mySprite(n).posY , _mySprite(n).toY , _mySprite(n).durationY )
inc _mySprite(n).timerUpdateY
endif
if _mySprite(n).fadeTimerUpdate = 0
resetValTimer( _mySprite(n).fadeTimerNum )
_mySprite(n).fadeDuration = rnd(5.5)+0.5
if sprite alpha(_mySprite(n).id) = _mySprite(n).alphaMin
_mySprite(n).fadeTo = _mySprite(n).alphaMax
else
_mySprite(n).fadeTo = _mySprite(n).alphaMin
endif
initValTimer( _mySprite(n).fadeTimerNum , _mySprite(n).fadeCur , _mySprite(n).fadeTo , _mySprite(n).fadeDuration )
inc _mySprite(n).fadeTimerUpdate
endif
_mySprite(n).posX = runValTimer( _mySprite(n).timerNumX )
_mySprite(n).posY = runValTimer( _mySprite(n).timerNumY )
_mySprite(n).fadeCur = runValTimer( _mySprite(n).fadeTimerNum )
paste sprite _mySprite(n).id,_mySprite(n).posX,_mySprite(n).posY
set sprite alpha _mySprite(n).id,_mySprite(n).fadeCur
next n
`debug
ink rgb(255,255,255),0
ts = text size()+2
text 0,0,"[Sasuke's Timer Sprite Demo]"
text 0,ts*1,"Sprite Count: "+str$(cMYSPRITE_COUNT)
text 0,ts*2,"Timer Count: "+str$(cMYSPRITE_COUNT*3)
text 0,ts*3,"fps: "+str$(screen fps())
sync
loop
function initOnSync( iRate as integer )
sync on : sync rate iRate
endfunction
function initDisplay( width as integer , height as integer , depth as integer , runMax as boolean , vSync as boolean )
if runMax > 0
load dll "user32.dll",1
g_iSystemWidth = call dll( 1 , "GetSystemMetrics" , 0 )
g_iSystemHeight = call dll( 1 , "GetSystemMetrics" , 1 )
delete dll 1
set display mode g_iSystemWidth,g_iSystemHeight,depth,vSync
else
set display mode width,height,depth,vSync
endif
create bitmap cBITDUMP , screen width() , screen height()
set current bitmap 0
backdrop on : color backdrop 0
endfunction
function findFreeSprite()
repeat
inc i
until sprite exist(i) = 0
endfunction i
function findFreeImage()
repeat
inc i
until image exist(i) = 0
endfunction i
type udt_gTimer
newTick as dword
oldTick as float
curTick as dword
lastTick as float
endtype
function init_gTimer()
global g_Timer as udt_gTimer
g_Timer.oldTick = timer()
g_Timer.lastTick = g_Timer.oldTick
endfunction
function update_gTimer()
g_Timer.newTick = timer()
g_Timer.curTick = g_Timer.newTick - g_Timer.oldTick
g_Timer.oldTick = g_Timer.newTick
endfunction
function findFreeValTimer()
array insert at bottom _valTimer()
out = array count(_valTimer())
endfunction out
function initValTimer( index as integer , fromVal as float , toVal as float , duration as float )
_valTimer(index).init = 0
_valTimer(index).ended = 0
_valTimer(index).fromVal = fromVal
_valTimer(index).toVal = toVal
_valTimer(index).lastTick = 0.0
_valTimer(index).duration = duration
endfunction
function resetValTimer( index as integer )
_valTimer(index).init = 0
_valTimer(index).ended = 0
_valTimer(index).fromVal = 0.0
_valTimer(index).toVal = 0.0
_valTimer(index).lastTick = 0.0
_valTimer(index).duration = 0.0
endfunction
function runValTimer( n as integer )
local time as float
local out as float
if _valTimer(n).ended > 0
out = _valTimer(n).toVal
exitfunction out
endif
if _valTimer(n).init < 1
_valTimer(n).lastTick = g_Timer.oldTick
_valTimer(n).init = 1
endif
time = (g_Timer.oldTick - _valTimer(n).lastTick ) / 1000.0
out = ((time * (_valTimer(n).toVal-_valTimer(n).fromVal)) / _valTimer(n).duration) + _valTimer(n).fromVal
if _valTimer(n).fromVal < _valTimer(n).toVal
if out >= _valTimer(n).toVal
out = _valTimer(n).toVal
_valTimer(n).ended = 1
exitfunction out
endif
else
if out <= _valTimer(n).toVal
out = _valTimer(n).toVal
_valTimer(n).ended = 1
exitfunction out
endif
endif
endfunction out
Now I set cMYSPRITE_COUNT to 512 for a real test and got round: 164 fps
That's 512 sprites each with 3 timers (1536 timers) that all randomally changing and are being tracked, I'd have to say that pretty damn good.
Enjoy
Note: if any of the code seems oddly indented, it's the forums fault.
A dream is a fantasy, if you achieve that fantasy it was never a dream to begin with.