I don't mean I make a bunch of function calls, I mean that I adjust based on a desired value per second (in the case below, 55 units per second at maximum walking speed) against the time elapsed since the last update.
regardless of framerate, this ensures that if 1 second has passed the character will be moved 55 units. if 0.5 seconds passsed, 27.5 units, if 10 seconds passed 550 units and so on. It doesn't attempt to smooth the movement and can create jumps at very low framerates, but it does keep the distance:time ratio constant
quick cutdown to relevant bits. the update function is called once per main loop
#CONSTANT FOOT_MAX_SPEED 55.0
#CONSTANT FOOT_ACCELERATION (SYSTEM.timing.loopsPerSec * 0.266)
type charBaseData
x as float
y as float
z as float
oldx as float
oldy as float
oldz as float
facing as float
oldfacing as float
heading as float
speed as float
timestamp as integer
elapsed as float
obj as integer
endtype
type charData
baseData as charBaseData
endtype
dim Chars() as charData
function framework_update_characters()
system_log(2, "main", "Begin Update: characters()")
updateMark as double integer
updateMark = hitimer()
for c = 0 to array count(Chars())
system_log(2, "chars", "Begin character update for character " + str$(c))
`store old data
Chars(c).baseData.oldfacing = object angle y(Chars(c).baseData.obj)
Chars(c).baseData.oldx = Chars(c).baseData.x
Chars(c).baseData.oldy = Chars(c).baseData.y
Chars(c).baseData.oldz = Chars(c).baseData.z
`get elapsed time in seconds
Chars(c).baseData.elapsed = (timer()-Chars(c).baseData.timestamp)/1000.0
dec Chars(c).baseData.elapsed, (SYSTEM.timing.pauseElapsed/1000.0)
`get current speed
Chars(c).baseData.speed = curvevalue(FOOT_MAX_SPEED, Chars(c).baseData.speed, FOOT_ACCELERATION)
`new position
Chars(c).baseData.x = Chars(c).baseData.x + sin(Chars(c).baseData.heading) * Chars(c).baseData.speed * Chars(c).baseData.elapsed
Chars(c).baseData.z = Chars(c).baseData.z + cos(Chars(c).baseData.heading) * Chars(c).baseData.speed * Chars(c).baseData.elapsed
`update the object
yrotate object Chars(c).baseData.obj,curveangle(Chars(c).baseData.facing,Chars(c).baseData.oldfacing,FOOT_TURN_SPEED)
position object Chars(c).baseData.obj, Chars(c).baseData.x, Chars(c).baseData.y, Chars(c).baseData.z
`time stamp update finished
Chars(c).baseData.timestamp = timer()
next c
system_log(2, "main", "End Update: characters()," + str$(hitimer() - updateMark))
endfunction