SDL_GetTicks and frame independent movement - how?

Started by
29 comments, last by Specchum 19 years, 11 months ago
now=SDL_GetTicks()/1000.0f;diff=last-now;//get input, draw, etc...last=now;

and the mooving function:
void Moving(int xp, int yp) {		if (direction==UP) {			if ((ypos-2)<56) {			turbing=false;			}		else {			turbing=true;			ypos-=(2*diff);		}	}	else if (direction==DOWN) {		if ((ypos+2)>565) {			turbing=false;		}		else {			turbing=true;		ypos+=(2*diff);		}	}	else if (direction==LEFT) {		if ((xpos-2)<0) {			turbing=false;		}		else {			turbing=true;		xpos-=(2*diff);		}	}	else if (direction==RIGHT) {					if ((xpos+2)>765) {			turbing=false;	}				else {			turbing=true;		xpos+=(2*diff);		}					}}


[edited by - ZadrraS on April 22, 2004 7:38:57 AM]
Advertisement
Come on someone, whats wrong? Ive came to the point where i can''t go any further without time based movement.
now=SDL_GetTicks()/1000.0f;
diff=last-now;
//get input, draw, etc...
last=now;

this is wrong... you should not take the time at the begining of your main loop AND at the end... this is wrong because your OS might decide to take over sometime during the middle of the app, and that last wont be correctly in- sync. (i might have worded that wrong, dont quote me on it).

the proper way would be to do this:

//main game loopwhile(!gameover){PreviousTime = CurrentTime;    //start the counter for FPS		CurrentTime = SDL_GetTicks();       //end the counter for FPS		FrameTime = (CurrentTime - PreviousTime) * 0.001f; //find the time elapsed in milliseconds and convert it to seconds by multiplying by .001//NOW do your whole game loop here!



do you see how this works? immediately in the begining of the loop we take the previous time, then right after we get the current time, then right after that we subtract the second one from the first. the first time this loop runs, there will probably be no difference in the 2 (obviously you would have to initialize current_time). but, when the loop goes around one time, it will get to previous time and assign that value to current_time (which would have happend an entire game loop ago), then current time is assigned the time. the subtracted amount is how much time passed during the game loop. now since each lines of code are right next to each other, the OS wont hog you and screw you over.



now, on to your movement code, yours looked ok but it seemed like you were incrementing it by a low number maybe?



   if (direction==UP)    {	if ((ypos-2)<56)         {	  turbing=false;	}	else        {	  turbing=true;	  ypos = yPos + (500 * FrameTime);	}   }


obviously i hard-coded 500. but you can play around with that value to get the speeds you want. hope i helped.



[edited by - graveyard filla on April 25, 2004 1:23:55 PM]

[edited by - graveyard filla on April 25, 2004 1:40:08 PM]

[edited by - graveyard filla on April 25, 2004 1:40:47 PM]
FTA, my 2D futuristic action MMORPG
Thanks gf, its not, nor the second time you help me . But whats the diffrence between this:
ypos = yPos + (500 * FrameTime);
and this:
ypos+=(30*diff);
i don''t see a diff...
your welcome. and there is no difference.. (besides 500 and 30) it just looks more clear-er to me in this situation
FTA, my 2D futuristic action MMORPG
hmmm, doesn''t work too framerate independant, it goes much faster up or left than down or right... Whats wrong?
void Moving(int xp, int yp) {		if (direction==UP) {			if (((ypos-2)<56) || (map[((yp-3)-56)/32][xp/32]!=OPEN) || (map[((yp-3)-56)/32][(xp/32)+1]!=OPEN)) {					direction=STOP;			turbing=false;					}					else {			turbing=true;			ypos+=(80*diff);		}	}	else if (direction==DOWN) {		if (((ypos+2)>565) || (map[(((yp+4)-56)/32)+1][xp/32]!=OPEN) || (map[(((yp+4)-56)/32)+1][(xp/32)+1]!=OPEN)) {								direction=STOP;			turbing=false;						}		else {			turbing=true;		ypos-=(80*diff);		}	}else if (direction==LEFT) {  if (((xpos-2)<0) || (map[(yp-56)/32][(xp-3)/32]!=OPEN) || (map[((yp-56)/32)+1][(xp-3)/32]!=OPEN)) {								direction=STOP;			turbing=false;						}		else {			turbing=true;		xpos+=(80*diff);		}	}	else if (direction==RIGHT) {			if (((xpos+2)>765) || (map[(yp-56)/32][((xp+3)/32)+1]!=OPEN) || (map[((yp-56)/32)+1][((xp+3)/32)+1]!=OPEN)) {			direction=STOP;					turbing=false;				}		else {			turbing=true;		xpos-= (80*diff);		}					}}

Don''y look at the assy collision detection
No, this is stupid. Ive been trying to figure out whats wrong with my code, but i don''t get it. Why my time based movement isn''t time based???
Get how many miliseconds it takes to process one frame (call it ''t'')
Use a point of reference, i.e 1 pixel/second. ( call it ''60'' )
Move your object by the ratio.

Since 1 second == 1000 miliseconds...

object.x += OBJECT_SPEED * t/1000 * 60;

Example:
if t = 20 (fps = 50):
object.x += OBJECT_SPEED * 20/1000 * 60;
object.x += OBJECT_SPEED * 1.2; // object moves a little bit faster

if t = 10 (fps = 100):
object.x += OBJECT_SPEED * 10/1000 * 60;
object.x += OBJECT_SPEED * 0.6; // object moves a little bit slower

if t = 16.6667 (fps = 60):
object.x += OBJECT_SPEED * 16.6667/1000 * 60;
object.x += OBJECT_SPEED * 1; // object moves at exact speed.

Yay!
I didn''t fully understand what you ment, and i didn''t really understand how would it solwe the problem... More explaining?
For example, you want your objects to move 60 pixels in one second (forget what I said 1 pixel/second, I was wrong). Then you decide at what fps your game will run at 'normal' speed. Let's say you pick 60. At 60 fps, your objects will move exactly 1 pixel each frame, right? 1 pixel/frame, 60 frames/second, 60 pixels/second.

So, at 60 fps, your game would run at 'normal' speed. Now, what if for some reasons the fps drops down to 1 fps, you want your objects to move 60 pixels on each frame now, right? Since your game only processes 1 frame in 1 second, and you have set the standard that your objects will move 60 pixels in 1 second, you want to move your object 60 pixels on that frame because it takes 1 second to process that frame. And the code I show you does that.

object.x += OBJECT_SPEED * time_elapsed/1000 * 60;

why dividing it by 1000? Because there are 1000 miliseconds in 1 second. Why multiplying with 60? Because you set it that way. If you want it 100, that's fine too. That means your game will run at 'normal' speed when fps reaches 100. Or:

object.x += OBJECT_SPEED * time_elapsed * 60/1000;

Maybe much better. 60 pixels/second == 60 pixels/1000 miliseconds.

[edited by - alnite on April 26, 2004 3:13:42 PM]

This topic is closed to new replies.

Advertisement