在一帧之后执行功能的最佳方法是什么?

时间:2009-03-23 00:07:18

标签: flex actionscript-3 flash timing

使用ActionScript3 for Flash Player 9+,在一帧之后调用“一次性”功能的最好方法是什么?

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

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

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

当然,我们可以从DisplayObject监听Event.ENTER_FRAME事件,但这对于一次性延迟函数调用来说似乎有些过分。

5 个答案:

答案 0 :(得分: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();
    }

}

我没有测试过那段代码,但希望你能得到这个想法......

答案 1 :(得分: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();
        }
    }
}

可能对某人有用。

答案 2 :(得分:0)

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

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

答案 3 :(得分: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!")
}

答案 4 :(得分:-2)

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

addEventListener(Event.ENTER_FRAME, function(e:Event):void
{
    removeEventListener(Event.ENTER_FRAME, arguments["callee"]);
    onceOffFunction();
}