A common approach I've seen to doing something like this (which is also the approach I use) is to have a position and a velocity (and usually an acceleration as well, for smooth movement):
Code: Select all
float x, y; // position
float vx, vy; // velocity [units / sec]
Calculate the velocity to move from <x,y> to <xf,yf> in t seconds, assuming constant velocity:
Code: Select all
void pointVelocity(float x, float y, float xf, float yf, float t, float& vx, float& vy)
{
float dx = xf - x;
float dy = yf - y;
vx = dx / t;
vy = dy / t;
}
Call an update function on every tick/frame, which increases your position by your velocity times the previous frame time:
Code: Select all
float update(float ft)
{
if (x < xf) {
x += vx * ft;
if (x > xf)
x = xf;
}
if (y < yf) {
y += vy * ft;
if (y > yf)
y = yf;
}
}
The part that needs explanation is the frame time (ft). This is the time that the previous frame took from start to finish, in seconds. In Allegro 5, you'd use a main loop like this:
Code: Select all
float ft = 0.0f; // first update will do nothing
while (running) {
float t0 = (float)al_get_time();
ALLEGRO_EVENT ev;
while (al_get_next_event(evq, &ev))
handleEvent(ev);
update(ft);
render();
ft = (float)al_get_time() - t0;
}
You multiply your velocity [unit / sec] by time [sec] to obtain [unit], which is compatible with the units of position [unit] and can be added. This has the bonus of being frame rate independent--the technique is a form of interpolation to ensure that movement will take place at the same speed on every computer. On a slow computer with a high frame time, the object might move to the destination in the span of one frame. On a fast computer, it might take thousands of frames. But it will never arrive earlier than expected, and as long as you compensate for extremely high values of ft, it will never move farther than desired.
I don't know the exact specifics of how you want things to be set up, but you can probably make this fit if you like the idea. For milliseconds, you'd just divide the number of milliseconds by 1000 to get t.
There are other ways to achieve something similar by using absolute time offsets that are stored slightly more locally, but then you have to worry about accumulators and such. Of course, you could use an accumulator with this technique instead of multiplying by ft, but you would lose the frame rate independence.
Hope this helps.