如何实现固定步骤循环?

时间:2009-03-15 15:22:20

标签: c# loops fixed

我试图在我的程序中创建一个固定的步骤循环,但由于某种原因,我似乎无法让它正常工作。基本上我需要的是一个循环:

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

或类似的东西,带有。我尝试过使用Thread.Sleep,但我不太确定它给了我一个真正的固定步骤循环,当我试图在this网站上实现解决方案时,我遇到了问题,因为我无法看到一种方法来保存受循环影响的对象的状态。这迫使我排除那部分,当循环中有许多物体时导致减速。

如何在不必经常保存循环中每个对象的状态的情况下获得固定的步骤循环?

3 个答案:

答案 0 :(得分:1)

你是否要求一个基本上每n个刻度运行的循环?这听起来像Timer。 BCL中有几个计时器。一个timer for servers或一个for Window Forms

您可以沿着这些方向使用它们。以下是伪代码,用于显示如何完成此操作。换句话说,如果你只是复制和粘贴,它可能无法编译。

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;
       }

               }

}

您还可以使用闭包来包装定义计时器的方法的状态。

修改

我读了这篇文章,我理解了这个问题;但是,您仍然可以使用计时器,但是您需要设置您的功能,以便在您设置物理引擎的每个时间间隔内调用引擎。

你是否正在使用WPF他们有一些事件,我认为这些事件会以稳定的速率为doign动画解雇。

修改

我更新了我的代码示例以向您展示我的解释,但基本上您所做的是为您的物理引擎定义一个间隔,然后您通过“循环/定时器无论什么”每次传递时需要做的是确定多少真实自上次迭代以来经过的时间。然后将该delta存储在Accumalator中,您将用它来倒数,直到您为自上次调用后错过的所有间隔调用物理引擎。

我挣扎的是,如果在这里使用计时器更好,然后让一个dedidicated线程休眠,或其他一些实现。

答案 1 :(得分:1)

如果您正在使用游戏引擎,则Timer可能无法正常工作。定时器没有足够的精度来处理固定的步进循环并使其保持规则。

您需要使用高精度计时器实现此功能。在这种情况下,您需要使用the Stopwatch class.这将允许您具有足够的精度来准确跟踪您的经过时间。

您只需要跟踪您想要更新的频率(在Ticks中),然后使用秒表来衡量每次更新所需的时间。之后,您可以使用Sleep()调用来阻止,但是在大多数系统上都会意识到睡眠的精度只有14-15 ms,即使您只睡眠0或1 ms。这可能会使您的循环速度过慢,因此您可能需要实现自旋锁或类似操作(while(等待){do something})。 Sleep()很好,因为它可以节省CPU,旋转锁会在你等待时吃CPU周期,但会给你更多的精确度。

答案 2 :(得分:0)

Thread.Sleep不会给你一个固定的步骤循环,它会等待给定的时间,然后让程序继续运行。实际频率取决于睡眠的准确程度以及程序在每一步运行相同数量的挂钟时间时的一致性。但是,如果你可以适应一些漂移,这可能是足够的,当然也是最容易的。

要获得一个真正的固定步骤循环,您需要的是interval timer,它在计时器到期时通过回调执行您的代码。请注意,这不再是一个循环,但是代码会定期执行,我认为,这就是你想要的。同样,可能存在一些漂移,因此您可能需要调整每个步骤的间隔,以便在需要更高精度时,下一个事件在正确的时间触发。它真的不可能使它完全准确 - 毕竟基于硬件的间隔定时器具有精确性 - 但希望你可以使它准确到达你的目的。