Skip to main content
GameDev.net gamedev.net
🔒 Locked

consistent movement animations

Started by eagerone Jun 26, 2010 at 6:38 AM 4 replies 950+ views
Original Post
eagerone
eagerone
I searched a lot with google, but I didn't find anything useful, except perhaps tweening, but I dont think it will solve my problem, since that is only for fast speeds.

Short:
The particle jumps forth instead of moving at a constant speed.

The problem is totaly eliminated when I turn vsync on (steady 60fps) and have a constant time step of 1. I tried setting the same speed with the normal update mode, but it jumps again - I'M PRETTY SURE THE PROBLEM LIES IN MY UPDATING

Additional:
it is a simple 2d sprite particle that moves a bit per ms.
particle.position.x += particle.speed.x*time_step;particle.position.y += particle.speed.y*time_step;

This function is called in my loop before render phase, given the time step calculated based on last update
last_update = Time();while(checkSystemMessageQue()!=QUIT){   elapsed = Time()-last_update;   if(elapsed>0){      particle.doStep(elapsed);      last_update = Time();   }   particle.doRender();}

Time = timeGetTime();
checkSystemMessageQue = parses every message on the message queue if there are any

Long:
The problem is that the sprite jumps forth every so often by an uneven amount, as if the step isnt called for a lot of time. This is not the case, because I have a steady fps of 1400, and it even occurs when I have vsync turned on. I used to do an update every frame, but than realised that that way the amount time elapsed between two updates can be really small and the update will get called with timesteps of 0. I than implemented a second version which you can see above. Didnt help much.

I tried rendering the particle only in screen pixels (minimal location change was 1pixel etc) but no improvements; I render an antialiased circle so slow speeds arent a problem, but I am suspecting this is only because the step is so small a skipped update isnt noticeable.

Thanks!

[Edited by - eagerone on June 27, 2010 2:07:01 AM]
Spoink
Spoink
This might have been a copy paste error but,

particle.position.y += particle.speed.x*time_step;
should use the particle.speed.y

Otherwise it looks flawless to me :)
eagerone
eagerone
it was :)

Now even the constant 60Hz fails with the sprite jumping ahead . I have no idea what is wrong, so I'll just go ahead and implement some shaders or something.


It probably is yet another simple bug I made somewhere along midnight coding.
Whatz
Whatz
If this was working before but is now broken, try adding some debug code to discover exactly where things are slowing down, and by how long. Find out for sure if the problem is the msg queue, the animation call, or the render call.

If the loop has never worked exactly right, google "Fix Your Timestep" for a great article on the subject. I think you should at least use a timer function that provides greater detail. Check out QueryPerformanceCounter and QueryPerformanceFrequency.
--- "A penny saved never boils."
eagerone
eagerone
My code is really simple, what I posted above is pretty much everything. I already tried debugging, which actually pointed out the 0 timestep bug but not anything else.

I also read fixing your timestep yesterday and will probably implement it later today, because debugging isnt working out for me :)

Might also try QueryPreformanceCounter, but I dont think I need the accuracy - the program isnt meant to render only one sprite

cheers
unbird
unbird
Quote:
Might also try QueryPreformanceCounter, but I dont think I need the accuracy

Probably, but you'll need a better accuracy than timeGetTime(). From the Windows SDK documentation:
Quote:
The default precision of the timeGetTime function can be five milliseconds or more, depending on the machine

For instance on my machine, the precision is 15 milliseconds. So for 15 ms I get a zero delta and then a 15ms jump.

By the way: With your loop you lose the time spent in your update function, since you call Time() twice. Probably not that a problem now, but the more time you spend there the more your internal game time will drift off the wall clock time. Better measure time only once per loop:

last_update = Time();while(checkSystemMessageQue()!=QUIT){   current = Time();   elapsed = current - last_update;   last_update = current;   // update and render ...}


Hope that helps

unbird

Topic Locked

This topic has been locked by a moderator. New replies are not allowed.

Sign in to reply to this topic.