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

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

或类似的东西,带有 .我尝试过使用 Thread.Sleep 但我不太确定它给了我一个真正的固定步骤循环,当我尝试在 由于我找不到保存受循环影响的对象状态的方法,因此我遇到了问题。这迫使我排除该部分,当循环中有许多对象时,这会导致速度减慢。

如何获得固定步长循环,而无需不断保存循环中每个对象的状态?

有帮助吗?

解决方案

如果您是在游戏引擎的工作,一个定时器可能会无法正常工作。计时器没有足够的精度来处理固定步循环,并保持有规律的。

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

你只需要跟踪的你要如何经常更新(在蜱),然后用秒表来测量它需要为每个更新的时间。在此之后,你有可能使用睡眠()调用阻止,但要意识到睡眠只会有14-15毫秒大多数系统上的精度,即使你只能睡0或1毫秒。这可能你的循环减慢太多,所以您可能需要实现一个自旋锁或同级(一段时间(等待){做某事})。睡眠()是不错的,因为这样可以节省CPU如果可以的话,自旋锁会吃,而你在等待CPU周期,但给你更精确。

其他提示

您是否要求一个基本上每 n 个周期运行一次的循环?这听起来像是一个 定时器. 。BCL 中有几个定时器。A 服务器定时器 或一个 对于窗口窗体.

您可以按照这些思路使用它们。以下是伪代码,旨在大体展示这是如何完成的。换句话说,如果您只是复制和粘贴,它可能无法编译。

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 动画。

编辑

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

我纠结的是,如果在这里使用计时器更好,那么有一个专用线程休眠,或者其他一些实现。

Thread.sleep代码是不会给你一个固定步循环,它只会等待的时间一定量它可以让你的程序继续之前。实际的频率将取决于你的计划是在每一步运行的挂钟时间是相同的,如何准确的睡眠是如何保持一致。如果你能容纳约漂移,不过,这可能是适当的和肯定是最简单的。

要获得真正的固定步循环,你需要的是一个的间隔定时器,当定时器期满通过回调执行代码。请注意,是不是一个真正的循环了,但你的代码被周期性地执行,这一点,我认为,你想要什么。再次,有可能是一些漂移,所以你可能需要在每一步调整的时间间隔,使得在正确的时间下一个事件触发,如果你需要更多的准确性。这是不是真的有可能使其完全准确的 - 甚至是基于硬件的间隔计时器有一个精确的,毕竟 - 但我希望你可以把它为你的目的不够准确。

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top