Actionscript 3.0:对于更新方法,使用ENTER_FRAME事件和TIMER事件有什么区别?

时间:2012-03-10 18:51:56

标签: actionscript-3 flash

我在将ENTER_FRAME和TIMER方法用于更新方法时,正在寻找一些比较。我在互联网上寻找了一些答案,但我仍然觉得很难理解。

是否有人能够帮助简化它们之间的差异?

4 个答案:

答案 0 :(得分:5)

计时器事件可以独立于swf的帧速率(到一个点)进行调度。它们可以比ENTER_FRAME事件更频繁或更少地发生,并且如果您关心计算的精度,则应该使用它们,因为它们发生在ENTER_FRAME覆盖的时间跨度之间。最常见的用例是物理引擎,您可能希望尽可能精确,因此希望以比Flash的fps更快的速度执行模拟。

此外,如果您希望在给定延迟后执行特定操作,则计时器可能很有用。例如,Timer可让您轻松地在10秒后执行操作。您只需将10000毫秒传递到Timer的构造函数中,然后10秒后将调度Timer事件。如果你要使用ENTER_FRAME,你需要手动跟踪每次帧更新所经过的时间,如果你想知道10秒过去的时间。

ENTER_FRAME事件与时间轴的渲染周期相关联,并且或多或少与您指定的帧速率相匹配。例如,如果您的帧速率为30fps,那么每秒将收到大约30个ENTER_FRAME事件。如果您有一个特别复杂的显示列表,或者您的逻辑需要特别长的时间来执行,您可能会收到更少。

答案 1 :(得分:2)

"enterFrame"将在每一帧上发送。

假设您的SWF为24fps:"enterFrame"每秒最多发送24次。

"timer"按设定的时间间隔发送。

假设你以50毫秒的延迟开始Timer"timer"每秒最多发送20次。

这些事件的实际频率取决于主机环境以及应用程序内部的情况。例如,如果你的for处理程序中有一个"timer"循环,你正在迭代一个1,000个元素的数组并对每个元素执行一些字符串操作,那么你可能会得到更少的"timer" 1}}事件比你的数组只包含10个元素。同样,如果用户的系统可用内存不足,则Flash Player可能无法执行SWF,这可能会降低调度这些事件的速度。

"enterFrame"直接取决于帧速率。 "timer"在某种程度上间接取决于帧速率。

因为你(或其他人)总是会在某种程度上“间接地”询问我的意思,这里有一个测试这两个事件的小型AS3应用程序:

package
{

import flash.display.*;
import flash.events.*;
import flash.utils.*;

public class Test extends Sprite
{
    private var timer:Timer = null;
    private var timerEventCount:int = 0;
    private var enterFrameEventCount:int = 0;
    private var startTime:Number = 0;

    public function Test()
    {
        timer = new Timer(20, 0);
        timer.addEventListener("timer", timerHandler);
        timer.start();

        addEventListener("enterFrame", enterFrameHandler);

        startTime = new Date().time;
    }

    private function timerHandler(event:Event):void
    {
        timerEventCount++;

        var timeElapsed:Number = new Date().time - startTime;

        //for (var i:int = 0; i < 4000; i++)
        //  trace("i", i);

        if (timeElapsed >= 1000) {
            // Stop timer after 1 second.
            timer.stop();

            removeEventListener("enterFrame", enterFrameHandler);

            trace(timerEventCount + " timer events and "
                    + enterFrameEventCount + " enterFrame events in "
                    + timeElapsed + " milliseconds.");
        }
    }

    private function enterFrameHandler(event:Event):void
    {
        enterFrameEventCount++;
    }
}

}

以12fps编译:

mxmlc Test.as -default-frame-rate=12

输出:

45 timer events and 12 enterFrame events in 1001 milliseconds.

以60fps编译:

mxmlc Test.as -default-frame-rate=60

输出:

29 timer events and 58 enterFrame events in 1010 milliseconds.

如您所见,较高的帧速率实际上会降低计时器的速度。我在Flash Player Debugger 10.3.181.34(10.3)中运行它;你的里程可能会有所不同。

最后,如果你取消注释for循环并以60fps再次运行它,你会看到我在说什么。

输出:

3 timer events and 3 enterFrame events in 1145 milliseconds.

答案 2 :(得分:1)

ENTER_FRAME是每次虚拟机的渲染循环运行时触发的事件,这是相对于影片的帧速率。例如,在Flash CS IDE中,如果将帧速率设置为30,则从根显示对象或阶段开始,每秒将触发30个ENTER_FRAME事件。

另一方面,计时器只是一个计时器。它仅根据系统时钟时间运行。例如,如果您设置一个延迟为1毫秒的计时器,那么该计时器将在启动后闪烁一毫秒,并且如果您启用它,将每隔一毫秒继续触发一次。我认为camus在他的回答中试图说的是这个过程独立于帧率运行。它完全基于检查系统时钟并触发已满足请求延迟的定时器的事件。这是通过存储定时器启动的系统时间在内部验证,然后重复检查当前系统时间,直到它大于或等于定时器延迟的保存时间加PLUS。例如:

timer.start() //Lets say current system time is 1000

计时器持续时间为1000,因此我们需要在系统时间大于或等于2000时触发此计时器。

checkTimers() //Loops, gets the current system

//If system time is greater than or equal to 2000, trigger timer with an event
dispatchEvent(Timer.TIME, etc, etc);

注意上面的&#34;代码&#34;只是伪代码来演示系统的基本原理。

答案 3 :(得分:0)

ENTER_FRAME与电影的帧速率有关。 TIMER事件应该是绝对的。