Sign in to follow this  
djc

Variable Timer (timesteps adjustable)

Recommended Posts

Hi Everybody, I'm currently looking into the development of a variable timer. "Variable" as in, a timer that can be slowed down (in order to create slow-motion effects etc). As a base, I'm using the StopWatch class provided in .NET 2.0 which internally uses the QueryPerformanceCounter. I've tried already things like....multiplying the tickCounter with a float between 0 and 1.0f but that would allow me to decrease the tickcount into the past, which obviously is very bad! Currently the timer is storing the total ticks since start of the timer and is returning the elapsed millisec (by multiplying it with the tickFrequency) when requested. I guess it would be easy to adjust the "speed" of the timer if I would store the elapsedMillisecs instead of the ticks and then just calculate the elapsedMillisecs since the last call and add them....then I could just calculate in the speed factor. But wouldn't that result in huge rounding errors? And if so, would that even matter in a game? I mean, the time should be used in a game to control animations, timebased events etc...and not to drive an atomic clock...... All ideas or sugguestions are greatly appreciated!!! -Dan

Share this post


Link to post
Share on other sites
First you get the normal issues with PC timers. Basically, they aren't all that they ought to be.

Once you have a high-speed timer, you use that to power your scheduler timer. [google] has lots of good links on those. Also there was a really good article on them in one of the game programming gems books (2 or 3?) that you should read. If you are too lazy, five seconds on Google gives this link that looks promising: http://weblogs.asp.net/justin_rogers/archive/2004/03/21/93653.aspx



Basically the game scheduler knows to run the event (animation, cinematic, whatever) at a given frequency. You can adjust that frequency to get your 'variable timer' that you are looking for.

A good game scheduler can do quite a bit more for you, like come up with running statistics, in-game profiling, keeping the system sane during debug breaks, integrate with an error logging system, and otherwise make your life a little easier.


Example:

You tell your scheduler the frequency to run your graphics timer (60Hz), collision response and physics (10Hz), and so on.

Lets say your scheduler timer is running at 10ms intervals. It wakes up the first time, and sees that it has to run two callbacks. It runs them, and goes back to sleep. It wakes up 10 ms later, sees that it has nothing to do, and goes back to sleep. It wakes up 10 ms later, sees that it needs to run the graphics callback, and goes back to sleep ....

To run your slow motion, you set the scheduler's timer to run half as fast. To pause your simulation (for debugging, or pause, or whatever) you have the scheduler just stop calling functions.

Share this post


Link to post
Share on other sites
I think you've already got the jist of it. I store my time steps as floats, where 1.000 = 1 second, as opposed to "ticks" @ 1000 = 1 second. That's easier to work with and library-unspecific.

When i want to slow/speed up time, i just multiply the time delta by some given amount:

time_delta = Timer.GetTimeDelta(); // my own class
time_delta *= time_multiplyer; // say 2.0 for double speed!

So really, the time delta hasn't physically changed, but objects that depend on time won't know the difference. They just believe whatever you tell them ;-)

Note that with this in place, implementing a proper "pause" in your game without screwing around with the event loop is easy:

time_multiplyer = 0; // pause!

Another neat trick is that you can multiply the time delta at any time in your engine. So you can group separate objects and only adjust time for some of them. For instance, you can slow down the main action objects for a cool slow-mo effect while keeping your GUI elements on the screen going at full speed. Or you can pause the action elements entirely and have the GUI still going (and responding to input). Or you can freeze/slow down enemies when you grab that proverbial Super-Mario stop-watch powerup. All sorts of fun things.

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this