For time based movements, I use a basic pos = pos + speed * lastframetime
When I move an object with constant speed during constant time, one
second for example, I have no problem to end the movement at the same
position in any framerate.
When I tried to include variable speed movement, this seems to be a
little more complicated to interpolate the speed variation.
I have made this little code to explain what I mean, it just need to
press space to start the test, runs a desired movement, decreases the
speed, and automatically ends ( with log in stdout.txt ).
( There is no function’s check because this is just a little test ) :
/*** code start ***/
#include <stdio.h>
#include <SDL/SDL.h>
#include <SDL/SDL_opengl.h>
int main( int argc, char** argv )
{
// framerate vars
int iCurrentTick = 0, iLastTick = 0, iTmpFPS = 0, iNextUpdate = 0;
float fFrameDuration;
// object vars
float fObjPosX = 0;
float fSpeed = 500.0f;
// other
BOOL bLoop = TRUE, bMoving = FALSE;
SDL_Event event;
// start
SDL_Init( SDL_INIT_VIDEO|SDL_INIT_TIMER );
SDL_GL_SetAttribute( SDL_GL_RED_SIZE, 5 );
SDL_GL_SetAttribute( SDL_GL_GREEN_SIZE, 5 );
SDL_GL_SetAttribute( SDL_GL_BLUE_SIZE, 5 );
SDL_GL_SetAttribute( SDL_GL_DOUBLEBUFFER, 1 );
SDL_SetVideoMode( 800, 600, 32, SDL_OPENGL );
glMatrixMode ( GL_PROJECTION );
glLoadIdentity ();
glOrtho( 0, 800, 0, 600, -1.0, 1.0 );
glMatrixMode ( GL_MODELVIEW );
// main loop
while( bLoop )
{
// EVENT SECTION
while( SDL_PollEvent( &event ) )
{
switch( event.type )
{
case SDL_QUIT:
{
SDL_Quit();
return 0;
}
case SDL_KEYDOWN:
if( event.key.keysym.sym == SDLK_ESCAPE )
{
SDL_Quit();
return 0;
}
if( event.key.keysym.sym == SDLK_SPACE )
bMoving = TRUE;
}
}
// UPDATE SECTION
if( bMoving )
{
float deltaf = fFrameDuration / 1000.0f;
fObjPosX += fSpeed * deltaf; // adjust the position
fSpeed -= 200.0f * deltaf; // adjust the speed
if( fSpeed <= 0.0f )
{
bMoving = FALSE;
SDL_Quit();
return 0;
}
printf( "FT=%.02f pos=%.02f speed=%.02f\n", fFrameDuration,
fObjPosX, fSpeed ); // logger
}
// DRAWING SECTION
glClearColor( 0, 0, 0, 0 );
glClear( GL_COLOR_BUFFER_BIT );
glLoadIdentity();
glTranslatef( fObjPosX, 300.0f, 0.0f );
glBegin(GL_TRIANGLES);
glColor3f( 255, 255, 0 );
glVertex3f( 10.5f, .0f, .0f );
glColor3f( 255, 0, 0);
glVertex3f( -10.5f, -10.25f, 0.0f );
glColor3f( 255, 0, 0 );
glVertex3f( -10.5f, 10.25f, .0f );
glEnd();
SDL_GL_SwapBuffers();
// FRAMERATE UPDATE
iCurrentTick = SDL_GetTicks();
fFrameDuration = iCurrentTick - iLastTick;
iLastTick = iCurrentTick;
// FPS count
iTmpFPS++;
if( iCurrentTick >= iNextUpdate )
{
iNextUpdate += 1000;
printf("FPS=%i\n", iTmpFPS );
iTmpFPS = 0;
}
}
return 0;
}
/*** code end ***/
Running at max speed ( 360/380 fps on my system ) the object position
ends at 625.
Running at 75 fps ( vsync forced from drivers ) the object position ends at 628.
I tried with different framerates ( with FPSmanager from sdl_gfx ),
and lower is the framerate, and greater is the ending position.
How to do a correct speed adjustment ?