[SDL] object's speed control against different framerates

C.Alvarez blubzouf at gmail.com
Fri Apr 27 07:48:58 PDT 2007


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 ?


More information about the SDL mailing list