Feb 16, 2008

Clase FrameScript

La clase MovieClip de AS3 tiene un método indocumentado llamado addFrameScript. Este método nos permite asociar una función a un número de frame. Esto significa que gracias a él podemos tener código en un punto concreto de nuestro timeline sin necesidad de codificar en Flash.

Su firma es:

[as3]public function addFrameScript(frame:int, func:Function):void;[/as3]

Pero… ¿por qué existe este método?

Si utilizamos un movieClip que tenga código en alguno de sus frames o más de un frame (sino sería compatible con Sprite) y éste cuenta con una clase asociada, si la clase no extiende de MovieClip, el compilador arroja el siguiente error:

1180: Call to a possibly undefined method addFrameScript.

En el artículo Programando en AS3 desde Flash CS3 (I) vimos que, en AS3, todo lo que hacíamos en el IDE de Flash acababa “transformándose” en clases.

Pues bien, addFrameScript es la forma que tiene el compilador para coger el código que tenemos dispersado en nuestros movieclips y añadirlo a nuestra clase. De ahí que si se dan las condiciones que hemos visto, el compilador nos muestra ese error, ya que intenta buscar un método addFrameScript en una clase que no lo define.

Sacando partido de addFrameScript

Utilizando esta función indocumentada y la nueva clase de AS3 FrameLabel, escribí hace algún tiempo una sencilla clase que nos permite añadir y eliminar código en un frame que contenga una o más etiquetas. La clase se llama FrameScript.

Para instanciar una nueva clase FrameScript debemos pasar un MovieClip en el constructor.

[as3]public function FrameScript(mc:MovieClip);[/as3]

Una vez creada, disponemos de dos métodos públicos:

[as3]// Asocia una función en el frame que marca la etiqueta
public function addScript(value:String, func:Function):void
// Elimina la función asociada a la etiqueta
public function removeScript(value:String):void
[/as3]

Utilizar etiquetas en vez del número del frame es mucho más intuitivo y permite modificar la longitud del timeline sin que nuestro código falle.

Algunas formas de utilizar FrameScript

Como variable de clase en caso que tengamos que acceder más de una vez a nuestra instancia:

[as3]// Variable de clase
private var fs:FrameScript;
// Constructor o metodo
fs = new FrameScript(mc);
fs.addScript(“labelFin”, finAnimacion);
// Metodo
private function finAnimacion():void {
mc.alpha = 0;
fs.removeScript(“labelFin”);
}[/as3]

Como variable local en caso que tengamos que acceder una única vez para asociar código:

[as3]// Variable de funcion
var fs:FrameScript = new FrameScript(mc);
fs.addScript(“labelFin”, finAnimacion);
// Función dentro de método
function finAnimacion():void{
mc.alpha = 0;
}[/as3]

Sin asignar variable (forma breve):

[as3]// Forma breve
new FrameScript(mc).addScript(“labelFin”, function():void { mc.alpha = 0 });
[/as3]

Y un ejemplo muy simple para ilustrar su uso: dos instancias de un mismo movieclip cuyo comportamiento es modificado al marcar el check.

This movie requires Flash Player 9

Descargar ejemplo

Algunas consideraciones

Gracias a este método podemos mantener todo el código encapsulado en nuestra clase sin necesidad de programar en la linea de tiempo. Incluso podemos añadir nuevas funcionalidades en tiempo de ejecución, no sólo de compilación.

Aunque en líneas generales es una buena práctica no tener el código “escampado” por el fla, el otro extremo puede ser igual de malo. Es más sencillo tener algunos frames con instrucciones sencillas tipo stop() que intentar sacar todo el código fuera.

Por otro lado, la mayoría de veces que un programador necesita meter código en un movieclip suele ser para sincronizar las animaciones. En estos casos sí que puede ser más conveniente utilizar FrameScript antes que tener un bloque de código similar a esto:

MovieClip(parent).stop();
MovieClip(parent).proyectil.visible = false;
MovieClip(parent.parent).finAnimacion();

Por último, addFrameScript es un método indocumentado. Esto significa que Adobe no garantiza que en futuras versiones del Flash Player se soporte, y en ese caso nuestras películas fallarían. De todas formas, es muy improbable que suceda algo así y nunca he visto que se haya dado este problema con otros métodos indocumentados.

Update (29/03/09): Iván Gajate me advierte de un error ya que el método addFrameScript trabaja con índice cero y se debe restar un frame para que asigne correctamente. La clase y los ejemplos ya están actualizados.

>> Descargar la clase FrameScript

Información del artículo

Post publicado el 16 de February de 2008 a las 20:20 por llops

Categorias: Utilidades

Etiquetas: , , ,

Comparte

1 trackback

6 comentarios

  • luis

    pues chido tutorial, y un bravo por este tipo de paginas constructivas!

  • Órale, no sabía de esta clase! Gracias Llops!

  • Marito_jeje

    Excelente¡¡ muy util y práctico, gracias por postear estos tips, estaremos pendientes de nuevos post. :)

  • Está genial, pero a mi no me funciona, he estado haciendo pruebas y es porque el valor de frame en la escena tiene base cero (el fotograma 1 es el 0), por lo que en la línea 83 con restarle un uno al valor devuelto es suficiente.

    [as3]
    if (label == frameLabel.name) return frameLabel.frame-1;
    [/as3]

    Es super útil, muchas gracias Llops.

  • Iván, como más tarde me has indicado tú mismo, el que tiene índice cero es el método addFrameScript, no la escena. Ya he actualizado la clase.

    Mil gracias! :)