2

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

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

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

我怎样才能得到一个固定的步进循环,而不必不断地保存循环中每个对象的状态?

4

3 回答 3

1

您是否要求一个基本上每 n 个刻度运行的循环?这听起来像一个Timer。BCL 中有几个计时器。一个用于服务器的计时器或一个用于 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 动画的事件。

编辑

我更新了我的代码示例以向您展示我的解释,但基本上您所做的是为您的物理引擎定义一个间隔,然后您在每次通过“循环/计时器”时需要做的事情是确定从那以后经过了多少实时时间最后一次迭代。然后,您将该增量存储在累加器中,您将使用该累加器进行倒计时,直到您为上次调用以来错过的所有间隔调用物理引擎。

我遇到的问题是,如果在这里使用计时器更好,那么让专用线程休眠,或者其他一些实现。

于 2009-03-15T15:43:17.787 回答
1

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

您需要使用高精度计时器来实现这一点。在这种情况下,您需要使用Stopwatch 类。 这将使您有足够的精度来准确地跟踪您的 elapsedTime。

您只需要跟踪您想要更新的频率(以 Ticks 为单位),然后使用秒表来测量每次更新所需的时间。之后,您可以潜在地使用 Sleep() 调用来阻止,但要意识到在大多数系统上 sleep 的精度只有 14-15 毫秒,即使您只休眠 0 或 1 毫秒。这可能会使您的循环减慢太多,因此您可能需要实现自旋锁或类似的东西(while (waiting) { do something })。Sleep() 很好,因为如果可以的话,它会节省 CPU,自旋锁会在你等待时消耗 CPU 周期,但会给你更高的精度。

于 2009-03-15T16:25:03.113 回答
0

Thread.Sleep 不会给你一个固定的步骤循环,它只会在让你的程序继续之前等待给定的时间。实际频率将取决于睡眠的准确程度以及程序在每一步运行相同数量的挂钟时间的一致性。但是,如果您可以适应一些漂移,这可能就足够了,而且肯定是最简单的。

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

于 2009-03-15T15:44:19.313 回答