Advertisement

SDL Smooth Sprite Movement

Started by May 28, 2002 08:33 AM
4 comments, last by werdy666 22 years, 5 months ago
hi i am having afew problems with moving a sprite fast and smooth. I can make it smooth by moving the sprite at 1 pixel but it is very slow, I can move the sprite 10 pixels at a time and it is at a good speed, but very jerky being moved 10 pixels a time! I have looked at putting in some sort of timer but it doesn't work like i want it to. Here is the code....


int main(int argc, char *argv[])
{
  Uint8* keys;

  if ( SDL_Init(SDL_INIT_AUDIO|SDL_INIT_VIDEO|SDL_INIT_TIMER) < 0 )
  {
    printf("Unable to init SDL: %s\n", SDL_GetError());
    exit(1);
  }
  atexit(SDL_Quit);

  screen=SDL_SetVideoMode(640,480,16,SDL_HWSURFACE|SDL_DOUBLEBUF|SDL_FULLSCREEN);
  if ( screen == NULL )
  {
    printf("Unable to set 640x480 video: %s\n", SDL_GetError());
    exit(1);
  }

  InitImages();
  DrawBG();
  
  int done=0;
  float deltatime= 0, lasttime= 0 ,now=0;
  while(done == 0)
  {
    SDL_Event event;


    while ( SDL_PollEvent(&event) )
    {
      if ( event.type == SDL_QUIT )  {  done = 1;  }

      if ( event.type == SDL_KEYDOWN )
      {
        if ( event.key.keysym.sym == SDLK_ESCAPE ) { done = 1; }
      }
    }
    keys = SDL_GetKeyState(NULL);
	
	now = SDL_GetTicks();
	deltatime = now - lasttime;
	
    if ( keys[SDLK_UP] ) { ypos -= deltatime*0.1; }
	if ( keys[SDLK_DOWN] ) { ypos += deltatime*0.1; }
	if ( keys[SDLK_LEFT] ) { xpos -= deltatime*0.1; }
    if ( keys[SDLK_RIGHT] ) { xpos += deltatime*0.1; }


	DrawScene();
lasttime = now;
}
return 0;
}

 
Can someone please point me in the right direction so i can have very fast moving sprites that are silky smooth? Thanks for your time Werdy666 [edited by - werdy666 on May 28, 2002 9:35:59 AM]
Timing, timing....

If you split up the increments (movement) between each frame it will appear smoother.

look up ''DeltaTime'' or varible frame timing.

,Jay
Advertisement
hmmm i get what u mean about timing, but i am having troubles implementing it.

here is some code....

in main....
    if ( keys[SDLK_UP] ) { ypos -= 1; }    if ( keys[SDLK_DOWN] ) { ypos += 1; }    if ( keys[SDLK_LEFT] ) { xpos -= 1; }    if ( keys[SDLK_RIGHT] ) { ypos += 1; }	newtime = SDL_GetTicks();	if (newtime-oldtime>20)		{			DrawScene();			printf ("%f\n",newtime-oldtime);			oldtime = newtime;		} 


my DrawScene routine is

void DrawScene(){  DrawIMG(back,0,0);  DrawIMG(image, xpos, ypos);  SDL_Flip(screen);} 


am i right in saying that every 2/500ths of a second my sprite should move 1 pixel?, however if i increase it to say every half second it moves 1 pixel, it doesn''t work. just disappears from the screen! lol

what do i have to change in my code to allow it to move fast and smooth? Can anyone give me some hints please? This has me stumped! damn why do we have to sleep!!!

Werdy666
What you are doing is moving the object at a fixed rate of (1000/20) 50fps assuming the sdl-gettickcount function is reliabe to that level of accuracy and that 1 tick is 1 milisec.

A better way is to use a fps counter and move each frame.


  if (timeGetTime()>LastTime+1000)    {    FPSRate=FPSCounter;    FPSCounter=0;    DeltaTime = 1/FPSRate; //DT=float    LastTime = timeGetTime();     }  


SpeedPerFrame = DeltaTime*SpeedPerSecond;
(count FPS after flips/present)

timeGetTime()
Header: (must also have windows.h included)
Library: winmm.lib


Using this method (Varible Speed/Step Timing) you maintain constant movement regardless of frame rate, but with a higher frame rate the movement is spaced out more and looks smoother.

,Jay


thanks for your reply!

i now have this as my loop

//check for key presses etc here    FPSCounter++;if (timeGetTime()>LastTime+1000)    	{    FPSRate=FPSCounter;    FPSCounter=0;    DeltaTime = 1/FPSRate; //DT=float         	xpos += (DeltaTime*100);	LastTime = timeGetTime();	DrawScene();	} 


now the 100 as i understand it would mean 100 pixels per second. When i run this, it moves at first then stops dead still! I still don't get why! lol i know its possible cause even on my amiga in AMOS basic it could move a sprite very quick and smooth! i must be just dumb or something! lol

It doesn't have anything to do with the fact that the xpos is an int? cause as far as i know u can't move a sprite 1/2 a pixel or anything....

Werdy666

[edited by - werdy666 on May 29, 2002 9:12:06 PM]
Only the code I supplied goes into the if statment, all else goes outside.

DeltaTime*SpeedPerSecond=SpeedPerFrame

more frames = more smoothness = lower deltatime

Its technicly better to use xpos as a float but thats upto you, it depends on what level of accuracy you need.



  //check for key presses etc here   if (timeGetTime()>LastTime+1000)    	{          FPSRate=FPSCounter;         FPSCounter=0;          DeltaTime = 1/FPSRate; //DT=float         		LastTime = timeGetTime();		}xpos+=(deltatime*100)FPSCounter++; DrawScene();  


,Jay

This topic is closed to new replies.

Advertisement