Control de la reproducción de clips de película

Flash Player 9 y posterior, Adobe AIR 1.0 y posterior

Flash utiliza la metáfora de una línea de tiempo para expresar animación o un cambio de estado. Cualquier elemento visual que emplee una línea de tiempo debe ser un objeto MovieClip o una ampliación de la clase MovieClip. Aunque se puede utilizar el código ActionScript para ordenar a cualquier clip de película que se detenga, se reproduzca o pase a otro punto de la línea de tiempo, no se puede utilizar para crear dinámicamente una línea de tiempo ni añadir contenido en fotogramas específicos; esto solo es posible en la herramienta de edición Flash.

Cuando se reproduce un clip de película, avanza por su línea de tiempo a la velocidad indicada en la velocidad de fotogramas del archivo SWF. Como alternativa, se puede sustituir esta configuración estableciendo la propiedad Stage.frameRate en ActionScript.

Reproducción de clips de película y detención de la reproducción

Los métodos play() y stop() permiten realizar el control básico de un clip de película a lo largo de su línea de tiempo. Por ejemplo, sea un símbolo de clip de película en el escenario que contiene una animación de una bicicleta moviéndose por la pantalla, con el nombre de instancia establecido en bicycle . Si se añade el código siguiente a un fotograma clave de la línea de tiempo principal,

bicycle.stop();

la bicicleta no se moverá (su animación no se reproducirá). El movimiento de la bicicleta puede empezar a través de alguna interacción del usuario. Por ejemplo, si hubiera un botón denominado startButton , el código siguiente en un fotograma clave de la línea de tiempo principal lo haría de forma que al hacer clic en el botón se reproduce la animación:

// This function will be called when the button is clicked. It causes the  
// bicycle animation to play. 
function playAnimation(event:MouseEvent):void 
{ 
    bicycle.play(); 
} 
// Register the function as a listener with the button. 
startButton.addEventListener(MouseEvent.CLICK, playAnimation);

Avance rápido y rebobinado

Los métodos play() y stop() no son la única manera de controlar la reproducción en un clip de película. También se puede avanzar o rebobinar manualmente la cabeza lectora a lo largo de la línea de tiempo con los métodos nextFrame() y prevFrame() . Cuando se llama a cualquiera de estos métodos, se detiene la reproducción, y la cabeza lectora avanza o rebobina un fotograma, respectivamente.

Utilizar el método play() equivale a llamar a nextFrame() cada vez que se activa el evento enterFrame del objeto de clip de película. De esta manera, se podría reproducir hacia atrás el clip de película bicycle añadiendo un detector de eventos para el evento enterFrame e indicando a bicycle que retroceda al fotograma anterior en la función de detector, como se muestra a continuación:

// This function is called when the enterFrame event is triggered, meaning  
// it's called once per frame. 
function everyFrame(event:Event):void 
{ 
    if (bicycle.currentFrame == 1) 
    { 
        bicycle.gotoAndStop(bicycle.totalFrames); 
    } 
    else 
    { 
        bicycle.prevFrame(); 
    } 
} 
bicycle.addEventListener(Event.ENTER_FRAME, everyFrame);

En la reproducción normal, si un clip de película contiene más de un fotograma, se reproducirá indefinidamente; es decir, que volverá al fotograma 1 si avanza más allá del último fotograma. Al utilizar prevFrame() o nextFrame() , este comportamiento no se produce automáticamente (llamar a prevFrame() cuando la cabeza lectora está en el Fotograma 1 no mueve la cabeza lectora al último fotograma). La condición if del ejemplo anterior comprueba si la cabeza lectora ha retrocedido al primer fotograma y la avanza hasta el último fotograma, creando un bucle continuo del clip de película que se reproduce hacia atrás.

Salto a otro fotograma y utilización de etiquetas de fotogramas

Enviar un clip de película a un nuevo fotograma es muy sencillo. Mediante una llamada a gotoAndPlay() o gotoAndStop() , el clip de película saltará al número de fotograma especificado como parámetro. Como alternativa, se puede pasar una cadena que coincida con el nombre de una etiqueta de fotograma. Se puede asignar una etiqueta a cualquier fotograma de la línea de tiempo. Para ello, hay que seleccionar un fotograma de la línea de tiempo e introducir un nombre en el campo Etiqueta de fotograma del inspector de propiedades.

Las ventajas de utilizar etiquetas de fotogramas en lugar de números se aprecian especialmente cuando se crea un clip de película complejo. Cuando el número de fotogramas, capas e interpolaciones de una animación es elevado, resulta útil etiquetar los fotogramas importantes con descripciones explicativas que representan los cambios en el comportamiento del clip de película; por ejemplo, "off" (fuera), "walking" (caminando) o "running" (corriendo). De esta forma se mejora la legibilidad del código y se logra una mayor flexibilidad, ya que las llamadas de código ActionScript para ir a un fotograma con etiqueta señalan a una sola referencia, la etiqueta, en lugar de a un número de fotograma específico. Si posteriormente se decide mover la cabeza lectora a un segmento específico de la animación en un fotograma diferente, será necesario modificar el código ActionScript manteniendo la misma etiqueta para los fotogramas en la nueva ubicación.

Para representar etiquetas de fotograma en el código, ActionScript 3.0 incluye la clase FrameLabel. Cada instancia de esta clase representa una sola etiqueta de fotograma y tiene una propiedad name , que representa el nombre de la etiqueta de fotograma especificado en el inspector de propiedades, y una propiedad frame que representa el número de fotograma del fotograma en el que está colocada la etiqueta en la línea de tiempo.

Para acceder a las instancias de FrameLabel asociadas con una instancia de clip de película, la clase MovieClip incluye dos propiedades que devuelven objetos FrameLabel directamente. La propiedad currentLabels devuelve un conjunto formado por todos los objetos FrameLabel de toda la línea de tiempo de un clip de película. La propiedad currentLabel devuelve una cadena que contiene el nombre de la etiqueta de fotograma encontrada más reciente en la línea de tiempo.

Supongamos que se crea un clip de película denominado robot y que se asignan etiquetas a los distintos estados de animación. Se podría configurar una condición que comprobara la etiqueta currentLabel para acceder al estado actual del robot, como en el código siguiente:

if (robot.currentLabel == "walking") 
{ 
    // do something  
}

Flash Player 11.3 y AIR 3.3 han añadido el evento frameLabel a la clase FrameLabel. Puede asignar un controlador de eventos a la instancia de FrameLabel que represente una etiqueta de fotograma. El evento se distribuye cuando la cabeza lectora accede al fotograma.

El siguiente ejemplo crea una instancia de FrameLabel para la etiqueta del segundo fotograma del conjunto de etiquetas de fotograma de MovieClip. Seguidamente, registra un controlador de eventos para el evento frameLabel :

var myFrameLabel:FrameLabel = robot.currentLabels[1]; 
myFrameLabel.addEventListener(Event.FRAME_LABEL, onFrameLabel); 
 
function onFrameLabel(e:Event):void { 
    //do something 
}

Trabajo con escenas

En el entorno de edición de Flash, se pueden utilizar las escenas para delimitar una serie de líneas de tiempo en las que avanzaría un archivo SWF. En el segundo parámetro de los métodos gotoAndPlay() o gotoAndStop() , se puede especificar una escena a la que enviar la cabeza lectora. Todos los archivos FLA comienzan con la escena inicial únicamente, pero se pueden crear nuevas escenas.

La utilización de escenas no es siempre el mejor enfoque, ya que presenta varios inconvenientes. Un documento de Flash que contenga varias escenas puede ser difícil de mantener, especialmente en entornos de varios autores. La utilización de varias escenas puede no ser eficaz en términos de ancho de banda, ya que el proceso de publicación combina todas las escenas en una sola línea de tiempo. Esto provoca una descarga progresiva de todas las escenas, incluso si no se reproducen nunca. Por estos motivos, a menudo se desaconseja utilizar varias escenas, a menos que se necesiten para organizar varias animaciones largas basadas en la línea de tiempo.

La propiedad scenes de la clase MovieClip devuelve un conjunto de objetos Scene que representan todas las escenas del archivo SWF. La propiedad currentScene devuelve un objeto Scene que representa la escena que se está reproduciendo actualmente.

La clase Scene tiene varias propiedades que ofrecen información sobre una escena. La propiedad labels devuelve un conjunto de objetos FrameLabel que representan las etiquetas de fotograma en dicha escena. La propiedad name devuelve el nombre de la escena como una cadena. La propiedad numFrames devuelve un entero que representa el número total de fotogramas en la escena.