Time based motion
I am having some problems getting time based motion to work correctly.
from what I know is you get the start time at the start of the game loop.
start_time = GetTickCount();
then when you want to move somthing you do
dt = GetTickCount() - start_time;
position += vel * dt;
when I do this the object will move choppy across the screen
is this because dt is zero (game loop is too quick?)??
Can anyone provide some asistance?
February 20, 2003 08:35 PM
First off:
You need to consider how quickly your two calls to GetTickCount are going to be spaced. GetTickCount BEST case has 1 ms accuracy, more on this in a minute. Therefore it is possibly to get a value of of 0 for dT.
Secondly:
GetTickCount is very unreliable. It will behave differently on different machines. In some cases it will have exactly 1 ms resolution in others it can have a latency of 50ms.
Instead of GetTickCount use timeGetTime and set its resolution to 1 ms using timeBeginPeriod and timeEndPeriod.
Others will tell you to use high resolution timers like QueryPerformance counter. Thats good advice too. But be careful with it when compared to timeGetTime, QueryPerformance counter is more expensive.
You need to consider how quickly your two calls to GetTickCount are going to be spaced. GetTickCount BEST case has 1 ms accuracy, more on this in a minute. Therefore it is possibly to get a value of of 0 for dT.
Secondly:
GetTickCount is very unreliable. It will behave differently on different machines. In some cases it will have exactly 1 ms resolution in others it can have a latency of 50ms.
Instead of GetTickCount use timeGetTime and set its resolution to 1 ms using timeBeginPeriod and timeEndPeriod.
Others will tell you to use high resolution timers like QueryPerformance counter. Thats good advice too. But be careful with it when compared to timeGetTime, QueryPerformance counter is more expensive.
February 20, 2003 10:28 PM
Another problem is that you are simulating only the time of your frame between the start of the frame and your update code.
To use an example, say your frame takes 10ms. Assume your simulation code happens at 4ms, with 6ms of code running afterwards. Your algorithm will move your object only 4ms worth, in 10ms of real time, meaning your object will appear to move at 40% of its desired speed.
What you want is to simulate an *entire* frame, every frame. But since you don''t have a magic computer with ESP that knows how long the current frame is going to take, you should instead simulate with the duration of the last frame.
To use an example, say your frame takes 10ms. Assume your simulation code happens at 4ms, with 6ms of code running afterwards. Your algorithm will move your object only 4ms worth, in 10ms of real time, meaning your object will appear to move at 40% of its desired speed.
What you want is to simulate an *entire* frame, every frame. But since you don''t have a magic computer with ESP that knows how long the current frame is going to take, you should instead simulate with the duration of the last frame.
quote: Original post by Anonymous Poster
Another problem is that you are simulating only the time of your frame between the start of the frame and your update code.
To use an example, say your frame takes 10ms. Assume your simulation code happens at 4ms, with 6ms of code running afterwards. Your algorithm will move your object only 4ms worth, in 10ms of real time, meaning your object will appear to move at 40% of its desired speed.
What you want is to simulate an *entire* frame, every frame. But since you don't have a magic computer with ESP that knows how long the current frame is going to take, you should instead simulate with the duration of the last frame.
Ok, I get what you mean. So would you do it like this where this is the point that the object is updated.
dt = current_time - last_time;
last_time = curren_time;
position += vel * dt;
Is this what you mean by the duration of the last frame?
(are there any other options to time based motion)
[edited by - drastick on February 20, 2003 11:57:19 PM]
Func: PrepareAnimationWhenItStarts ()
{
FramesTotal = 25; // Generally, let`s say you have 25 frames of animation.
AnimationLength = 2.0f; // Animation shall take 2 seconds;
This helps us to find out when should we render next frame:TimeFrameLength = AnimationLength / FramesTotal;
AnimationStartTime = getcurrenttime (your time function); // Animation starts at current time;
AnimationEndTime = AnimationStartTime + AnimationLength; // When should animation stop:
Time of last frame that has been rendered lastly: LastFrameTime = AnimationStartTime;
CurrentAnimationFrame = 0;
}
at Render ():
...
Func in Render : UpdateAnimation (curentTime)
RenderFrame (CurrentAnimationFrame)
...
UpdateAnimation ()
{
timedifference = currentTime - LastFrameTime;
if (timesdifference > timeFrameLength)
{
framesdifference = (int) (timedifference / TimeFrameLength); // this shows how many frames should we skip if the program had been slowed down somewhere - i.e. we skip frames that couldn`t be rendered when they should have been - i.e. hdd swapping or something
CurrentAnimationFrame+= framesdifference;
If currentanimationframe>(FramesTota-1) Finishanimation
LastFrameTime = currenttime;
}
}
Put it all in a class (CAnimationClass), and every animated character may be in different instance of class which means you are having any number of characters being animated at any time. If you make an array of it CAnimationClass Enemies [EnemmiesCount], at Render you just do: for (int cEnemy=0; cEnemy{
Enemies [cEnemy].Update...
Enemies [cEnemy].Render...
}
Naturally the data representation will depend on your needs. But this way you can make a dynamic array at level load-time and work with them easily in array.
It`s not interpolating anything - it`s up to you. Collision detection when game stutters (and the character would make it into the wall when some frames are skipped) is also up to you, but I think you`re now dealing with basics so this should be enough for starting you up.
Hope that helps
VladR
[edited by - VladR on February 21, 2003 5:03:06 AM]
[edited by - VladR on February 21, 2003 5:04:25 AM]
[edited by - VladR on February 21, 2003 7:32:46 AM]
{
FramesTotal = 25; // Generally, let`s say you have 25 frames of animation.
AnimationLength = 2.0f; // Animation shall take 2 seconds;
This helps us to find out when should we render next frame:TimeFrameLength = AnimationLength / FramesTotal;
AnimationStartTime = getcurrenttime (your time function); // Animation starts at current time;
AnimationEndTime = AnimationStartTime + AnimationLength; // When should animation stop:
Time of last frame that has been rendered lastly: LastFrameTime = AnimationStartTime;
CurrentAnimationFrame = 0;
}
at Render ():
...
Func in Render : UpdateAnimation (curentTime)
RenderFrame (CurrentAnimationFrame)
...
UpdateAnimation ()
{
timedifference = currentTime - LastFrameTime;
if (timesdifference > timeFrameLength)
{
framesdifference = (int) (timedifference / TimeFrameLength); // this shows how many frames should we skip if the program had been slowed down somewhere - i.e. we skip frames that couldn`t be rendered when they should have been - i.e. hdd swapping or something
CurrentAnimationFrame+= framesdifference;
If currentanimationframe>(FramesTota-1) Finishanimation
LastFrameTime = currenttime;
}
}
Put it all in a class (CAnimationClass), and every animated character may be in different instance of class which means you are having any number of characters being animated at any time. If you make an array of it CAnimationClass Enemies [EnemmiesCount], at Render you just do: for (int cEnemy=0; cEnemy{
Enemies [cEnemy].Update...
Enemies [cEnemy].Render...
}
Naturally the data representation will depend on your needs. But this way you can make a dynamic array at level load-time and work with them easily in array.
It`s not interpolating anything - it`s up to you. Collision detection when game stutters (and the character would make it into the wall when some frames are skipped) is also up to you, but I think you`re now dealing with basics so this should be enough for starting you up.
Hope that helps
VladR
[edited by - VladR on February 21, 2003 5:03:06 AM]
[edited by - VladR on February 21, 2003 5:04:25 AM]
[edited by - VladR on February 21, 2003 7:32:46 AM]
VladR My 3rd person action RPG on GreenLight: http://steamcommunity.com/sharedfiles/filedetails/?id=92951596
February 22, 2003 09:53 PM
quote:
dt = current_time - last_time;
last_time = curren_time;
position += vel * dt;
Is this what you mean by the duration of the last frame?
Sure, that would work.
This topic is closed to new replies.
Advertisement
Popular Topics
Advertisement