用于movieclip结束的flash事件监听器?

时间:2011-05-12 16:14:34

标签: flash actionscript-3 flash-cs5

有人建议在动画片段动画结束时触发功能的最佳方法吗? 我认为事件监听器可以处理这个问题,但不确定最好的方法。 谢谢 保罗

8 个答案:

答案 0 :(得分:10)

有几种方法可以解决这个问题:

  1. 只需从动画的最后一帧调用该功能。
  2. 在您的功能的最后一帧发送一个事件,并在其他地方收听。
  3. 长而有效/整洁/推荐的方式。
  4. 参考第3点,我会为你的对象创建一个基类。这样,您可以将相同的逻辑应用于动画的多个元素。

    这样的事情:

    package
    {
        import flash.display.MovieClip;
        import flash.events.Event;
    
        public class AnimatingObject extends MovieClip
        {
            // constants
            public const ANIMATION_COMPLETE:String = "animation_complete";
    
            /**
             * Constructor
             */
            public function AnimatingObject()
            {
                addEventListener(Event.ENTER_FRAME, _handle);
            }
    
            /**
             * Called on dispatch of Event.ENTER_FRAME
             */
            private function _handle(e:Event):void
            {
                if(currentFrame == totalFrames)
                {
                    var evt:Event = new Event(ANIMATION_COMPLETE);
                    dispatchEvent(evt);
                }
            }
        }
    }
    

    现在我们可以收听“animation_complete”并做相应的事情。

    package
    {
        import flash.events.Event;
    
        public class MyAnimatingObject extends AnimatingObject
        {
            /**
             * Constructor
             */
            public function MyAnimatingObject()
            {
                addEventListener(ANIMATION_COMPLETE, _lastFrame);
            }
    
            /**
             * Called on dispatch of AnimatingObject.ANIMATION_COMPLETE
             */
            private function _lastFrame(e:Event):void
            {
                trace("i'm done");
            }
        }
    }
    

答案 1 :(得分:3)

自从我玩flash之后已经有一段时间了。我现在大部分时都在弯曲,但这应该有效 使用enterFrame事件会浪费大量资源,创建自定义事件类并不是必需的。 在最后一帧放这个

dispatchEvent(new Event("INSERTSTUPIDEVENTNAMEHERE"));

在你的“root”代码中

movieInstanceName.addEventListener( "INSERTSTUPIDEVENTNAMEHERE", someCallBackFunction );

function someCallBackFunction ( e:Event ):void{
  trace( "Last frame hit");
}

答案 2 :(得分:2)

通过使用ENTER_FRAME监听器,您可以判断MovieClip是否已经重新开始播放;然后,您可以将它包装在一个将为您执行监视的Wrapper类中更进一步:

public class EndOfMovieClipEventDispatcher extends EventDispatcher
{
    private var target : MovieClip;
    private var endReachedEvent : String;

    public function EndOfMovieClipEventDispatcher(target : MovieClip, endReachedEvent : String = "complete") {
        this.target = target;
        this.endReachedEvent = endReachedEvent;
        target.addEventListener(Event.ENTER_FRAME, onEnterFrameEvent, false, 0, true);
    }

    public function destroy() : void {
        target.removeEventListener(Event.ENTER_FRAME, onEnterFrameEvent);
    }

    private function onEnterFrameEvent(event : Event) : void
    {
        if (target.currentFrame == target.totalFrames) {
            dispatchEvent(new Event(endReachedEvent));
        }
    }
}

用法非常简单;由于弱事件监听器,对destroy()的调用是可选的;但建议你完成:)

new EndOfMovieClipEventDispatcher(myMovieClip).addEventListener(Event.COMPLETE, onMovieClipCompleteEvent);
myMovieClip.play();

答案 3 :(得分:0)

我不相信在动画片段结尾处有一个事件广播,你总是可以在动画的最后一帧上运行一个脚本来执行你想要的。如果你真的想要使用事件,那么movieclip的最后一帧可以执行一个脚本,该脚本利用dispatchEvent()发送自定义,甚至可以拾取它。

我不确定你以前是否使用过eventhandler,所以这里有一个教程(我不擅长解释,抱歉!): http://edutechwiki.unige.ch/en/ActionScript_3_event_handling_tutorial

和dispatchEvent(): http://www.actionscript.org/resources/articles/204/1/Using-EventDispatcher/Page1.html

答案 4 :(得分:0)

您可以使用一个enterframe监听器来检查movieclip的currentFrame == totalFrames,如果它们相等,则调度您所做的自定义事件(如TimelineComplete)。

另一种选择是创建一个小组件来调度您的自定义TimelineComplete事件,并将该组件放在您要监视的任何动画的最后一帧上。这样您就可以在将来获得更多创意,并在触发事件之前添加延迟等内容。

你有一些选择,在我看来,这些选项都不是理想的,但是它们确实有效,如果做得好,它们就不会变得笨拙。我不会做的一件事是在最后一帧上添加一些代码。随着时间的推移,这很难跟踪。

答案 5 :(得分:0)

您可以创建一个自定义MovieClip类,在影片剪辑对象位于最后一帧时调度事件。然后,您可以将自定义MovieClip类作为影片剪辑动画的基类:

CustomMovieClip.as:

package display 
{
    import events.TimelineEvent;
    import flash.display.MovieClip;
    import flash.events.Event;

    public class CustomMovieClip extends MovieClip
    {
        private var _isLastFrame:Boolean;

        public function get isLastFrame():Boolean { return _isLastFrame }

        public function CustomMovieClip()
        {
            init();

        }// end function

        private function init():void
        {
            addEventListener(Event.ENTER_FRAME, onEnterFrame);

        }// end function

        private function onEnterFrame(e:Event):void
        {
            if (!_isLastFrame)
            {
                if (currentFrame == totalFrames) 
                {
                    dispatchEvent(new TimelineEvent(TimelineEvent.LAST_FRAME));
                    _isLastFrame = true;

                }// end if

            }
            else 
            {
                if (currentFrame != totalFrames) _isLastFrame = false;

            }// end else

        }// end function

    }// end class

}// end package

TimelineEvent.as:

package events
{   
    import flash.events.Event;

    public class TimelineEvent extends Event 
    {
        public static var LAST_FRAME:String = "lastFrame";

        public function TimelineEvent(type:String, bubbles:Boolean=false, cancelable:Boolean=false) 
        { 
            super(type, bubbles, cancelable);

        }// end function

        public override function clone():Event 
        { 
            return new TimelineEvent(type, bubbles, cancelable);

        }// end function

    }// end class

}// end package

Main.as(文档类):

package 
{
    import display.CustomMovieClip;
    import events.TimelineEvent;
    import flash.display.Sprite;
    import flash.events.Event;

    public class Main extends Sprite 
    {
        public function Main():void 
        {
            if (stage) init();
            else addEventListener(Event.ADDED_TO_STAGE, init);

        }/// end function

        private function init(e:Event = null):void 
        {
            removeEventListener(Event.ADDED_TO_STAGE, init);

            var customMovieClip:CustomMovieClip = new CustomMovieClip();
            customMovieClip.addEventListener(TimelineEvent.LAST_FRAME, onCustomMovieClipLastFrame);
            customMovieClip.play();

        }// end function

        private function onCustomMovieClipLastFrame(e:TimelineEvent):void
        {
            var customMovieClip:CustomMovieClip = CustomMovieClip(e.target);
            customMovieClip.removeEventListener(TimelineEvent.LAST_FRAME, onCustomMovieClipLastFrame);

            trace(customMovieClip.isLastFrame); // output: true

        }// end function

    }// end class

}// end package

答案 6 :(得分:0)

如果寻找最短的解决方案我认为它会是:

        mc.addFrameScript(mc.totalFrames - 1, function():void 
        {
            trace("end of mc");
        });

答案 7 :(得分:0)

仅检查currentFrametotalFrames对于具有多个场景的MovieClip是不够的。您还必须检查它是否在最后一个场景。

function isAtLastFrame(mc:MovieClip):Boolean
{
  return currentScene.name == mc.scenes[mc.scenes.length - 1].name && currentFrame == currentScene.numFrames;
}