2

对于 Flash Player 9+ 的 ActionScript3,在恰好一帧之后调用“一次性”函数的最佳方式是什么?

我知道 Timer 类及其用途,以及 Flex UIComponents 上的 callLater 方法(浏览源代码,在这种情况下看起来效率不高)。我也知道 setTimeout(在 flash.utils 中)。

Timer 类和 setTimeout 实用程序都是基于时间的,那么我们如何保证我们的函数会在一帧之后被调用呢?

从我有限的测试来看,传递给 setTimeout 的函数似乎只在至少一帧后执行(尝试将延迟设置为 0)。但这不能保证。

当然,我们可以从 DisplayObject 侦听 Event.ENTER_FRAME 事件,但这对于一次性延迟函数调用来说似乎是多余的。

4

5 回答 5

3

Flex 旨在抽象出 Flash Player 的基于帧的特性,因此您不会找到太多可以帮助您解决问题的方法。最好的方法是按照您的建议收听 ENTER_FRAME 。如果这太过分了(我不确定你为什么这么认为),你可以创建一个辅助类,它接受一个 DisplayObject 和 Function 作为参数,它会自动为你添加/删除 ENTER_FRAME 事件侦听器。

public class NextFrameCommand() {

    private var functionToCall : Function;

    public function NextFrameCommand(dObj: DisplayObject, func : Function) {
        functionToCall = func;
    }

    public function start() : void {
        dObj.addEventListener(Event.ENTER_FRAME, onEnterFrame);
    }

    private function onEnterFrame(e : Event) : void {
        e.target.removeEventListener(Event.ENTER_FRAME, onEnterFrame);
        functionToCall.call();
    }

}

我还没有测试过那个代码,但希望你能明白......

于 2009-03-23T01:13:14.893 回答
1

使用 Theo 和 brd6644 提供的解决方案,我带来了这个。它允许多个函数(带参数)在下一帧按顺序排列和执行。

public class DelayedFunctionQueue
{
    protected var queue:Array;
    protected var dispatcher:Sprite;

    public function DelayedFunctionQueue()
    {
        queue = new Array();
        dispatcher = new Sprite();
    }

    public function add( func:Function, ... args ):void
    {
        var delegateFn:Function = function():void
        {
            func.apply( null, args );
        }
        queue.push( delegateFn );
        if ( queue.length == 1 )
        {
            dispatcher.addEventListener( Event.ENTER_FRAME, onEF, false, 0, true );
        }
    }

    protected function onEF( event:Event ):void
    {
        dispatcher.removeEventListener( Event.ENTER_FRAME, onEF, false );
        queue = queue.reverse();
        while ( queue.length > 0 )
        {
            var delegateFn:Function = queue.pop();
            delegateFn();
        }
    }
}

可能对某人有用。

于 2009-03-23T17:28:21.273 回答
0

一种方法是查看您的项目设置为每秒多少帧,并让 setTimeout 函数在该设置内延迟 1 帧时间。

因此,如果您的项目设置为每秒 24 帧,则在 setTimeout 中延迟 42 毫秒。

于 2009-03-23T00:19:41.793 回答
0
var timerSprite:Sprite = new Sprite();

timerSprite.addEventListener(Event.ENTER_FRAME, oneFrameHandeler);

function oneFrameHandeler(e:Event):void
{
   timerSprite.removeEventListener(Event.ENTER_FRAME, oneFrameHandeler);
   timerSprite = null;

   trace("one frame later!")
}
于 2009-03-23T01:15:49.007 回答
-2

ENTER_FRAME 并不过分——这样的事情很简单

addEventListener(Event.ENTER_FRAME, function(e:Event):void
{
    removeEventListener(Event.ENTER_FRAME, arguments["callee"]);
    onceOffFunction();
}
于 2013-10-21T16:27:25.550 回答