прослушиватель флеш-событий для конца мувиклипа? - PullRequest
9 голосов
/ 12 мая 2011

Может ли кто-нибудь посоветовать лучший способ запуска функции по окончании анимации мувиклипа?Я полагаю, что EventListener мог бы справиться с этим, но не уверен, что лучший способ сделать это.Спасибо, Пол

Ответы [ 8 ]

10 голосов
/ 13 мая 2011

Есть несколько способов сделать это:

  1. Просто вызовите функцию из последнего кадра вашей анимации.
  2. Отправка события в последнем кадре вашей функции и прослушивание его в другом месте.
  3. Долгий, но эффективный / аккуратный / рекомендуемый способ.

Что касается пункта 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");
        }
    }
}
3 голосов
/ 13 мая 2011

Прошло немного времени с тех пор, как я играл со вспышкой.Сейчас я в основном сгибаюсь, но это должно работать.Использование события enterFrame было бы огромной тратой ресурсов, и создание пользовательского класса событий не является обязательным.На последнем кадре поместите это

dispatchEvent(new Event("INSERTSTUPIDEVENTNAMEHERE"));

И в вашем коде на свой "корень"

movieInstanceName.addEventListener( "INSERTSTUPIDEVENTNAMEHERE", someCallBackFunction );

function someCallBackFunction ( e:Event ):void{
  trace( "Last frame hit");
}
2 голосов
/ 13 мая 2011

Используя прослушиватель 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();
0 голосов
/ 13 апреля 2013

Только проверка currentFrame и totalFrames недостаточна для мувиклипа, содержащего несколько сцен. Вы также должны проверить, находится ли он в последней сцене.

function isAtLastFrame(mc:MovieClip):Boolean
{
  return currentScene.name == mc.scenes[mc.scenes.length - 1].name && currentFrame == currentScene.numFrames;
}
0 голосов
/ 12 апреля 2012

Если вы ищете кратчайшее решение, я думаю, что это будет:

        mc.addFrameScript(mc.totalFrames - 1, function():void 
        {
            trace("end of mc");
        });
0 голосов
/ 13 мая 2011

Вы можете создать собственный класс 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
0 голосов
/ 12 мая 2011

Вы можете использовать прослушиватель enterframe, который проверяет, является ли currentFrame мувиклипа == totalFrames, и, если они равны, отправляет пользовательское событие, которое вы делаете (например, TimelineComplete).

Другой вариант будетсоздайте небольшой компонент, который отправляет ваше пользовательское событие TimelineComplete, и поместите этот компонент в последний кадр любой анимации, которую вы хотите отслеживать.Это позволит вам стать более креативным в будущем и добавить такие вещи, как задержка до запуска события.

У вас есть несколько вариантов, ни один из которых, на мой взгляд, не идеален, однако они работаюти если все сделано хорошо, они не станут громоздкими.Единственное, чего я бы не стал делать, это добавить немного кода в последний кадр.Это становится довольно сложно отслеживать с течением времени.

0 голосов
/ 12 мая 2011

Я не верю, что в конце видеоклипа происходит трансляция события, вы всегда можете запустить сценарий в последнем кадре анимации, чтобы выполнить то, что вы хотите. Если вы действительно хотите использовать события, последний кадр мувиклипа может выполнить скрипт, который использует dispatchEvent () для отправки пользовательского даже, который может быть выбран.

Я не уверен из вашего поста, использовали ли вы ранее обработчики событий, так что вот урок об этом (я не умею объяснять, извините!): http://edutechwiki.unige.ch/en/ActionScript_3_event_handling_tutorial

и для dispatchEvent (): http://www.actionscript.org/resources/articles/204/1/Using-EventDispatcher/Page1.html

...