在我的游戏引擎中,有些对象需要定期更新。例如,一个场景可以降低它的 alpha,所以我设置了一个间隔来做到这一点。此外,相机有时需要稍微抖动一下,这需要对旋转属性进行插值。
我看到有两种方法可以处理这些问题:
有一个调用所有其他对象的更新方法的 update() 方法。对象跟踪自上次更新以来的时间并采取相应措施。
setInterval
为每个对象的更新方法做一个。
什么是最好的解决方案,为什么?
在我的游戏引擎中,有些对象需要定期更新。例如,一个场景可以降低它的 alpha,所以我设置了一个间隔来做到这一点。此外,相机有时需要稍微抖动一下,这需要对旋转属性进行插值。
我看到有两种方法可以处理这些问题:
有一个调用所有其他对象的更新方法的 update() 方法。对象跟踪自上次更新以来的时间并采取相应措施。
setInterval
为每个对象的更新方法做一个。
什么是最好的解决方案,为什么?
setInterval
不遵守时钟,它只是在事件进入时对其进行排序。浏览器倾向于在事件之间至少保留一些少量的时间。因此,如果您有 10 个事件都需要在 100 毫秒后触发,您可能会看到最后一个事件在 200 毫秒后触发。(这很容易测试)。
从这个意义上说,只有一个事件(并对所有对象调用更新)比让每个对象设置它自己的间隔更好。尽管可能还有其他考虑因素,但至少出于这个原因,选项 2 是不可行的。
这里有更多关于setInterval
浏览器如何确定 setInterval 应该使用什么时间?
我发现制作一个好的 update() 函数并保持良好的帧速率和更少的负载的最佳方法如下。
有一个update()
绘制框架的方法,通过循环所有可绘制对象的某种队列/调度,他自己的update()
函数被添加到这个更新事件队列/调度中。(事件监听器)
这样,您不必循环所有未安排重绘/更新的对象(如菜单按钮或十字准线)。并且您没有为所有可绘制对象运行过多的间隔。
我建议update()
在setInterval
.
另外,我猜几个 setintervals 运行的时间是不可靠的。
另一种可能性,取决于您的游戏中发生的其他事情,使用一堆单独的间隔可能会在计分和比较得分等时引入竞争条件
所提出的算法并不是相关方法所独有的。也就是说,您可以使用 setInteval 调用所有的更新方法,也可以通过重复调用 setTimeout 让每个对象自行更新。
更重要的是,单个计时器比多个计时器(任一类型)的开销更少。当你有很多计时器时,这真的很重要。另一方面,只有一个计时器可能不适合,因为某些对象可能需要比其他对象更频繁地更新,或者更新到不同的时间表,所以尽量减少它们。
setTimeout 的一个优点是可以调整到下一次调用的间隔以满足特定的调度要求,例如,如果一个延迟,您可以跳过下一个或提前进行。setInterval 将相对于一致的时钟缓慢漂移,并且一次调整更加困难。
另一方面, setInteval 只需要调用一次,因此您不必一直调用计时器。你最终可能会得到一个组合。