2011-05-12 40 views
9

任何人都可以建議在動畫片段動畫結束時觸發函數的最佳方法嗎? 我想一個eventlistener可以處理這個,但不知道最好的辦法去做。 謝謝 保羅movieclip結束的flash事件監聽器?

+1

處理類似的事情此刻。最簡單的選擇是對ENTER_FRAME事件使用事件偵聽器,並檢查當前幀是否是最後一個(例如,函數checkLastFrame(event:Event):void {trace(currentFrame == totalFrames);}),但取決於簡單或複雜的,你可能會發現以下資源得心應手:http://www.adobe.com/devnet/flash/articles/timelinewatcher.html,http://www.bytearray.org/?p=603,http:// www .tink.ws/blog/framelabelmovieclip-uiframelabelmovieclip/ – 2011-05-12 16:29:56

+0

爲你的幫助而歡呼喬治 – Dancer 2011-05-12 16:37:54

+0

爲什麼你不能在最後一幀發射一個事件? – 2011-05-12 21:59:01

回答

0

我不相信在電影剪輯結束時有一個事件廣播,你可以隨時在動畫的最後一幀運行腳本來執行你想要的。如果您確實想要使用事件,則動畫片段的最後一幀可以執行一個腳本,該腳本利用dispatchEvent()發送一個可以拾取的自定義腳本。

我不是從您的帖子知道你以前使用過事件處理器,所以這裏的上一個教程(我不擅長解釋,對不起!): http://edutechwiki.unige.ch/en/ActionScript_3_event_handling_tutorial

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

0

您可以使用一個enterframe偵聽器來檢查movieclip的currentFrame == totalFrames是否相等,並調度您製作的自定義事件(如TimelineComplete)。

另一種選擇是創建一個小組件,以調度您的自定義TimelineComplete事件,並將該組件放置在您想要監視的任何動畫的最後一幀上。這可以讓您在將來獲得更多創意,並在事件觸發前添加延遲等內容。

你有幾個選擇,其中沒有一個在我看來是理想的,但是他們確實有效,如果做得好,他們不會變得笨拙。我不會做的一件事是在最後一幀添加一些代碼。隨着時間的推移,這很難跟蹤。

2

通過使用ENTER_FRAME監聽器,您可以判斷MovieClip是否已經播放結束;那麼你可以藉此更進一步,在一個包裝類包裹起來,會爲你執行監視:

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

您可以創建自定義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 
10

有幾種方法可以解決這個問題:

  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

自從我玩過閃存以來已經有一段時間了。我現在主要做flex,但這應該工作。
使用enterFrame事件會造成資源的巨大浪費,創建自定義事件類並不是必需的。 在最後一幀這個

dispatchEvent(new Event("INSERTSTUPIDEVENTNAMEHERE")); 

並在你的「根」

movieInstanceName.addEventListener("INSERTSTUPIDEVENTNAMEHERE", someCallBackFunction); 

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

如果您在Flash中將時間線上的代碼放在代碼中,但您可能無法訪問原始.fla或甚至希望在時間軸上放置代碼,因爲這可能會令人困惑。另外,我不會完全調用enterFrame事件對資源的「巨大」使用。 – jhocking 2011-05-13 18:35:58

0

你的代碼,如果找最短的解決方案把我認爲這將是:

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

只檢查對於具有多個場景的MovieClip而言,currentFrametotalFrames是不夠的。你還必須檢查它是否在最後一個場景。

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