有人可以建议最好的方法来触发一个函数当一个MovieClip动画结束时吗?我想使用事件侦听器来处理这个问题,但不确定最佳方法是什么。谢谢。Paul
有人可以建议最好的方法来触发一个函数当一个MovieClip动画结束时吗?我想使用事件侦听器来处理这个问题,但不确定最佳方法是什么。谢谢。Paul
有几种方法可以实现这个目标:
关于第三点,我建议您为对象创建一个基类。这样,您就可以将相同的逻辑应用于多个正在执行动画的元素。
像这样:
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");
}
}
}
我已经有一段时间没有使用Flash了。现在我主要使用Flex,但这应该也可以用。
使用enterFrame事件会浪费大量资源,而创建自定义事件类并不必要。
在最后一帧上添加以下内容:
dispatchEvent(new Event("INSERTSTUPIDEVENTNAMEHERE"));
movieInstanceName.addEventListener( "INSERTSTUPIDEVENTNAMEHERE", someCallBackFunction );
function someCallBackFunction ( e:Event ):void{
trace( "Last frame hit");
}
通过使用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();
我不认为在影片剪辑结束时有事件广播,你可以在动画的最后一帧运行一个脚本来执行你想要的操作。如果你真的想使用事件,影片剪辑的最后一帧可以执行一个脚本,利用dispatchEvent()发送自定义事件,这样就能接收到。
我无法确定你是否使用过事件处理程序,所以这里有一个教程(我不太擅长解释,抱歉!): http://edutechwiki.unige.ch/en/ActionScript_3_event_handling_tutorial
至于dispatchEvent(): http://www.actionscript.org/resources/articles/204/1/Using-EventDispatcher/Page1.html
你可以使用一个enterframe监听器来检查电影剪辑的currentFrame是否等于totalFrames,如果相等,则触发你自己创建的自定义事件(如TimelineComplete)。
另一种选择是创建一个小组件来触发你的自定义TimelineComplete事件,并将该组件放置在任何你想要监视的动画的最后一帧上。这将允许你在未来更有创意地添加延迟触发事件等功能。
你有几个选择,但我认为都不是理想的选择,但它们确实有效,如果做得好,它们不会变得难以控制。唯一不建议的是在最后一帧上添加一点代码,因为随着时间的推移,这会变得非常难以跟踪。
仅检查currentFrame
和totalFrames
不足以处理具有多个场景的MovieClip。您还必须检查它是否在最后一个场景。
function isAtLastFrame(mc:MovieClip):Boolean
{
return currentScene.name == mc.scenes[mc.scenes.length - 1].name && currentFrame == currentScene.numFrames;
}
如果寻找最短的解决方案,我认为应该是:
mc.addFrameScript(mc.totalFrames - 1, function():void
{
trace("end of mc");
});
您可以创建一个自定义的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