2011-05-12 4 views
9

¿Alguien podría aconsejar la mejor manera de activar una función cuando termina una animación de clip de película? Me imagino que un eventlistener podría manejar esto, pero no estoy seguro de la mejor manera de hacerlo. Gracias Pauloyente de evento flash para movieclip end?

+1

haciendo algo similar por el momento. La opción más fácil es usar un detector de eventos para el evento ENTER_FRAME y verificar si el marco actual es el último (por ejemplo, checkLastFrame de función (evento: Event): void {trace (currentFrame == totalFrames);}), pero dependiendo de qué tan simple o complejo, puede encontrar los siguientes recursos a mano: http://www.adobe.com/devnet/flash/articles/timelinewatcher.html, http://www.bytearray.org/?p=603, http: // www. .tink.ws/blog/framelabelmovieclip-uiframelabelmovieclip/ –

+0

Saludos por su ayuda George – Dancer

+0

¿Por qué no puede simplemente iniciar un evento en el último fotograma? –

Respuesta

0

No creo que haya un evento transmitido al final de un clip de película, siempre se puede ejecutar un script en el último fotograma de una animación para ejecutar lo que desee. Si realmente desea utilizar eventos, el último fotograma del clip de película podría ejecutar una secuencia de comandos que utiliza dispatchEvent() para enviar una acción personalizada que se puede recoger.

no estoy seguro de su cargo si ha utilizado manejadores de sucesos antes, así que aquí hay un tutorial sobre eso (que no soy bueno para explicar, lo siento!): http://edutechwiki.unige.ch/en/ActionScript_3_event_handling_tutorial

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

0

se podría utilizar un oyente enterFrame que comprueba para ver si currentFrame del clip de película == totalFrames, y si son iguales, despachar un evento personalizado que haga (como TimelineComplete).

Otra opción sería crear un pequeño componente que distribuya su evento TimelineComplete personalizado, y colocar ese componente en el marco final de cualquier animación que desee supervisar. Esto le permitiría ser más creativo en el futuro y agregar cosas como un retraso antes de que se desencadene el evento.

Tiene algunas opciones, ninguna de las cuales es ideal en mi opinión, sin embargo funcionan, y si se hacen bien, no se volverán difíciles de manejar. Lo único que no haría es agregar un poco de código en el último fotograma. Eso se vuelve bastante difícil de seguir a lo largo del tiempo.

2

Al utilizar un oyente ENTER_FRAME, puede decir si un MovieClip ha leído el final de la reproducción; a continuación, puede tomar un paso más allá envolviéndolo en una clase de contenedor que va a realizar el seguimiento para usted:

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)); 
     } 
    } 
} 

El uso es bastante sencillo; la llamada a destroy() es opcional gracias al oyente de eventos débiles; pero se recomienda si ha terminado :)

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

Se puede crear una clase personalizada MovieClip que distribuye un evento cuando el objeto de clip de película está en el último fotograma. A continuación, puede hacer que la costumbre MovieClip clase de la clase base de la secuencia de animación de la película:

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 (clase de documento) :

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

Hay varias maneras de hacerlo:

  1. Simplemente llame a la función desde el último cuadro de la animación.
  2. Despacha un evento en el último cuadro de tu función y escúchalo en otro lugar.
  3. La manera larga pero efectiva/ordenada/recomendada.

En referencia al punto 3, crearía una clase base para su objeto. De esta forma puede aplicar la misma lógica a múltiples elementos animados.

Algo como esto:

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); 
      } 
     } 
    } 
} 

Ahora podemos escuchar "animation_complete" y hacer cosas en consecuencia.

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

Ha sido un tiempo desde que jugué con flash. Mayormente doy flexibilidad ahora, pero esto debería funcionar.
Usar el evento enterFrame sería una gran pérdida de recursos, y no es necesario crear una clase de evento personalizada. En el último cuadro a poner esto

dispatchEvent(new Event("INSERTSTUPIDEVENTNAMEHERE")); 

Y en su código en su "raíz"

movieInstanceName.addEventListener("INSERTSTUPIDEVENTNAMEHERE", someCallBackFunction); 

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

Esta respuesta funciona si coloca el código en la línea de tiempo en Flash, pero es posible que no tenga acceso al .fla original o incluso quiera poner el código en la línea de tiempo porque a veces puede ser confuso. Además, no llamaría exactamente al evento enterFrame un uso "enorme" de recursos. – jhocking

0

si en busca de solución más corta que creo que sería:

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

Sólo cheque currentFrame y totalFrames no es suficiente para un MovieClip que tiene varias escenas. También debe verificar si está en la última escena.

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