I posted some code for timer based curvevalue functions a while ago, but the functions weren't very efficient, and were prone to exploding. I have since improved the functions, to use an optimised formula, here is the code:
remstart
Better Time Based Curvevalue and Curveangle functions
By Joseph Thomson
10/3/06
If you've ever used the curvevalue and curveangle functions in a program with variable
frame rate, then you'll be aware that they don't work too well under changes in speed.
These functions act exactly like the DBPro functions, but they are loop speed independent.
The only difference is you need to input the time variable. A time of 1 makes the functions
run just like the DBPro functions. Lower makes it run slower (less time step), and higher
makes it run faster (bigger time step).
remend
`Variables
global loopSpeed as float
global wrapangle as float = 0.0
global syncrate as integer = 60
`Set sync rate
sync on
sync rate 60
autocam off
`Make pointer
make object cone 1,10
xrotate object 1,90
fix object pivot 1
make object cone 2,10
xrotate object 2,90
fix object pivot 2
ghost object on 2
`Camera
position camera 0,15,0
xrotate camera 90
do
if inkey$()="1" then mode = 0
if inkey$()="2" then mode = 1
wrapangle = wrapvalue(wrapangle+(keystate(52)-keystate(51))*2.0)
rotate object 2,0,wrapangle,0
`Rotate pointer with left and right keys
if leftkey() = 1
rotate object 1,0,wrapvalue(object angle y(1)-loopSpeed*2),0
else
if rightkey() = 1
rotate object 1,0,wrapvalue(object angle y(1)+loopSpeed*2),0
else
`Otherwise use curve functions to put it back
if mode = 0 then rotate object 1,0,TCurveAngle(wrapangle,object angle y(1),20,loopSpeed),0
if mode = 1 then rotate object 1,0,TCurveValue(wrapangle,object angle y(1),20,loopSpeed),0
endif
endif
`Control sync rate
syncrate = syncrate + upkey()-downkey()
if syncrate < 5 then syncrate = 5
sync rate syncrate
`Calculate loopSpeed variable
loopSpeed = 60.0/1000.0 * (timer()-time)
time = timer()
`Text info
if mode = 0 then text 0,0,"CurveAngle Mode. Press 2 to switch to CurveValue mode"
if mode = 1 then text 0,0,"CurveValue Mode. Press 1 to switch to CurveAngle mode"
text 0,20,"Set Sync Rate: "+str$(syncrate)
text 0,40,"Actual FPS: "+str$(screen fps())
text 0,60,"LoopSpeed: "+str$(loopSpeed)
sync
loop
remstart
print "1000ms intervals (standard rate)"
start# = 50.0
aim# = 0.0
speed# = 2.0
value# = start#
for x = 1 to 5
value# = TCurveValue(aim#,value#,speed#,1)
print value#
next x
print
print "100ms intervals (10x rate)"
value# = start#
for x = 1 to 5
for y = 1 to 10
value# = TCurveValue(aim#,value#,speed#,0.1)
next y
print value#
next x
print
print "10ms intervals (100x rate)"
value# = start#
for x = 1 to 5
for y = 1 to 100
value# = TCurveValue(aim#,value#,speed#,0.01)
next y
print value#
next x
wait key
end
remend
`Curvevalue function. Requires loopSpeed variable
function TCurveValue(dest as double float, current as double float, speed as double float, time as double float)
local diff as double float
local value as double float
`Find difference between destination and current position
diff = dest - current
`Caluclate new value
value = current+diff*(1.0/speed)^time
endfunction value
`Curveangle function. Requires loopSpeed variable
function TCurveAngle(dest as double float, current as double float, speed as double float, time as double float)
local diff as double float
local value as double float
current = wrapvalue(current-dest)
`Find difference between destination and current position
if current < 180.0
diff = -current
else
diff = 360-current
endif
`Caluclate new value
value = wrapvalue(current+diff*(1.0/speed)^time)
endfunction value
