Question

I am attempting to create a fixed step loop in my program, but for some reason I just can't seem to get it to work properly. Basically what I need is a loop that does:

while(!over) {
    Update(elapsedtime);
    Draw(elapsedtime);
}

or something similar, with a . I've tried using Thread.Sleep but I'm not so sure it gave me a real fixed step loop, and when I tried to implement the solution on this website I had problems due to the fact that I couldn't see a way to save the state of the objects affected by the loop. This forced me to exclude that part, which led to slowdown when there were many objects in the loop.

How can I get a fixed step loop without constantly having to save the state of every object in the loop?

Was it helpful?

Solution

If you are working on a game engine, a Timer will probably not work well. Timers do not have enough accuracy to handle a fixed step loop and keep it regular.

You'll need to implement this using a high precision timer. In this case, you'll want to use the Stopwatch class. This will allow you to have enough precision to track your elapsedTime accurately.

You'll just need to keep track of how frequently you want to update (in Ticks), then use a stopwatch to measure the time it takes for each of your updates. After that, you can potentially use a Sleep() call to block, but realize that sleep will only have a precision of 14-15 ms on most systems, even if you only sleep for 0 or 1 ms. This may slow down your loop too much, so you may need to implement a spin lock or similar (while (waiting) { do something }). Sleep() is nice because it saves CPU if you can, the spin lock will eat CPU cycles while you're waiting, but gives you more precision.

OTHER TIPS

Are you asking for a loop which will run basically every n ticks? This sounds like a Timer. There are a couple of timer's in the BCL. A timer for servers or one for Window Forms.

You can use them along these lines. The following is psuedo code and meant to show generally how this is done. In other words it probably won't compile if you just copy and paste.

public class RepeatingTask
{
    public MyObjectState _objectState;

    public RepeatingTask(Timespan interval)
    {
       Timer timer=new Timer(Timer_Tick); //This assumes we pass a delegate. Each timer is different. Refer to MSDN for proper usage
       timer.Interval=interval;
       timer.Start();

    }
    private DateTime _lastFire;
    private void Timer_Tick()
    {
       DateTime curTime=DateTime.Now();
       DateTime timeSinceLastFire = curTime-lastFireTime;
       _lastFire=DateTime.Now(); //Store when we last fired...

       accumulatedtime+=timeSinceLastFire
       while(accumulatedtime>=physicsInterval)
       {
          Update(physicsInterval);
          accumulated-=physicInterval;
       }

               }

}

You can also use a closure to wrap up your state of the method which the timer is defined in.

Edit

I read the article and I understand the issue; however, you could still use a timer, but you need to as he indicates set your function up to call the engines for each interval you set your physics engine to.

Are you using WPF they have some events I believe which get fired at steady rates for doign animations.

Edit

I updated my code sample to show you my interpretation but basically what you do is define an interval for your physics engine, and then what you need to do on each pass through your "Loop / Timer whatever" is determine how much real time passed since the last iteration. You then store that delta in an Accumalator, which you will use to count down until you've called your physics engine for all the intervals that you missed since you last called.

What I struggle with is if using a timer here is better, then having a dedidicated thread sleeping, or some other implementation.

Thread.Sleep is not going to give you a fixed step loop, it will simply wait the given amount of time before it lets your program continue. The actual frequency will depend on how accurate the sleep is and how consistent your program is in running the same amount of wall clock time at each step. If you can accommodate some drift, though, this might be adequate and is certainly the easiest.

To get a real fixed step loop, what you need is an interval timer that executes your code via a callback when the timer expires. Note that isn't really a loop anymore, but you code gets executed periodically, which is, I think, what you want. Again, there may be some drift and so you may need to adjust the interval at each step so that the next event fires at the right time if you need more accuracy. It's not really possible to make it perfectly accurate -- even hardware-based interval timers have a precision, after all -- but hopefully you can make it accurate enough for your purposes.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top