随着时间的推移,计时器类似乎会产生很多错误,所以我想知道人们为更准确的计时器提出了哪些其他解决方案。 谢谢!
答案 0 :(得分:2)
显然,你可以足够准确地测量延迟,所以我假设你在延迟后尝试发射事件并且你的分辨率不够好。
是的,Timer类有点可怕。但你可以使用另一个技巧:
如果您需要2ms的延迟(例如),只需使用while循环:
var startTime:Number = getTimer();
while(getTimer() < startTime + 2) {
// whee
}
doStuff();
不言而喻,doStuff
在2ms之后才会执行。
显然不要将此用于比帧长更长的延迟,因为它会导致播放器变得迟钝。使用Timer关闭,然后在你足够接近时使用这个技巧。你会得到更好的分辨率。
如果您需要触发多个事件,则需要提前对其进行排序。
答案 1 :(得分:1)
我认为考虑到Flash架构是不可能的。基本上,flash中的每一步都分为几个步骤(除此之外还有更多的步骤,它们可能会有不同的名称,但总体而言我们说它是如何工作的):
所以,假设您有一个以20 FPS工作的应用程序,每50ms生成一个帧。您的输入帧事件需要10毫秒,绘制屏幕需要10毫秒,因此在每个帧中您只剩下30毫秒来捕获定时器事件。如果您的计时器是1ms,每帧20次,则必须等待Enter Frame和Drawing完成。非常糟糕,考虑到所有这些阶段可能需要更多时间的事实,并且Flash有这种倾向,不时有任何明显的原因,因此你处境更糟。
当然我可能在某个地方出错了,但除非你知道一些秘密成分,否则我认为不可能做到这一点。
答案 2 :(得分:1)
不完全确定您的问题和情况会有所不同,但Flash中的许多与时间相关的问题可以通过执行以下操作来解决:
这有效地使Flash Player遵循主时间轴的时间(因为它已将音频同步到流),而不是试图跟上每个图形帧。
通常我这样做是为了确保动画在不同的机器上以相同的速率播放,但我也用它来修复计时器的晃动。
答案 3 :(得分:0)
我之前在AS2遇到过这个问题,但我发现AS3更可靠。
我用as2做的是将计时器设置为比其他情况下运行大约少100毫秒。然后我会让它坚持前面描述的getTimer()循环,直到达到所需的时间,然后我会让它做任何事情。在99%的情况下,这不是一个好主意。循环使用了很多cpu,如果你的事件可能仍然超过100毫秒,这取决于CPU负载。
总而言之,在AS3中运行最简单的Timer测试之后,我发现偏移量非常一致,并且在小CPU负载下运行时非常可靠。
就解释而言,它更多的是一种观点,我对用于计算累积时间漂移的逻辑感到不满。
作者添加了所有的差异,所以让我们说当getTimer在1000,2002,3002时会触发一个事件。 这是两次迟到2ms,这并不意味着第二个事件是迟到4ms,迟到2ms,与之前的事件相比,它恰好相隔1000ms,所以不会迟到。因此,虽然数学有意义,但2 + 2 = 4,我真的不知道它在任何方面都有用。
当我运行测试时: var delay:int = 1000;
var myTimer:Timer = new Timer(delay, 0);
function timerHandler($evt:TimerEvent){
trace(getTimer());
}
myTimer.addEventListener(TimerEvent.TIMER, timerHandler);
myTimer.start();
trace(getTimer());
我在运行一些视频时得到了几秒钟:
15011 16011 17011 18054 19054 20054 21054 22054 23057 24054 25054 26054 27054 28011 29011 30011 31011 ... 135047 136194 <- big one here 137246 - and here 138167 - 139242 - 140173 - 141016 <- back 142018 <- normalized 143018 144018 145019 146018 147018
看到这种“正常化”很有意思。它有时会持续54毫秒,然后下降到27毫秒,然后上升到18毫秒等,然后在那里停留一段时间,然后再围绕另一个值进行标准化。但这个值不是累积的,而是非常接近基数。即。偏移量不会持续上升。如果您重复创建一次使用的事件,您会看到累积差异。