有人建议在动画片段动画结束时触发功能的最佳方法吗? 我认为事件监听器可以处理这个问题,但不确定最好的方法。 谢谢 保罗
答案 0 :(得分:10)
有几种方法可以解决这个问题:
参考第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)
仅检查currentFrame
和totalFrames
对于具有多个场景的MovieClip是不够的。您还必须检查它是否在最后一个场景。
function isAtLastFrame(mc:MovieClip):Boolean
{
return currentScene.name == mc.scenes[mc.scenes.length - 1].name && currentFrame == currentScene.numFrames;
}