Dec 21, 2007

Programando en AS3 desde Flash CS3 (III)

Vamos con el tercer y último artículo de la serie, dedicado a la forma en que se utilizan los objetos que tenemos en la librería de Flash.

Este artículo es menos técnico que los anteriores, pero dado que el cambio es bastante significativo (ya no se utiliza más attachMovie) merece la pena tratarlo.

Desde flash 5, cuando queríamos utilizar un símbolo de la librería de manera dinámica, le dábamos un nombre de identificador y con “attachMovie” lo vinculábamos a nuestra película. En flash 8, además, teníamos un campo para asociar el clip a una clase de ActionScript 2.

Panel de vinculación de Flash 8

Para cualquier programador actionscript, la sintaxis de attachMovie le resultará tan familiar como engorrosa. Gracias a Dios, en Flash CS3 esto ha pasado a mejor vida.

Utilizando clips de la biblioteca en CS3

Como ya hemos comentado en los artículos anteriores, en AS3 todo se traduce a clases, así que si queremos utilizar un clip que tenemos en nuestra librería tenemos que crear una nueva clase. Vamos a verlo paso a paso.

Dibujamos una bola en el escenario de Flash y la transformamos a MovieClip (F8). En la biblioteca, seleccionamos nuestro MovieClip y buscamos la opción de Linkage.

Librería y panel de vinculación de Flash CS3

Marcamos el checkbox Export for ActionScript y se activan dos campos de texto. En el primero ponemos BolaClass, que será el nombre de nuestra clase. El segundo, como el nombre indica, es la clase de la cual hereda (podemos usar la clase base que queramos, lo veremos luego). De momento dejamos MovieClip. Al darle OK veremos que aparece el siguiente mensaje:

A definition for this class could not be found in the classpath, so one will be automatically generated in the SWF file upon export.

Flash nos advierte que no encuentra BolaClass en su ruta de clases, así que generará una clase automáticamente al exportar. Al igual que pasa con el document Class, cuando Flash CS3 necesita una clase y no la encuentra la genera él mismo. El mismo mensaje aparece si le damos al check verde o al lápiz.

Ahora que ya tenemos el clip exportado para ActionScript podemos crear bolas dinámicamente. El código es más fácil, limpio e intuitivo que attachMovie.

[as3]var bola = new BolaClass(); // crea un nuevo objeto bolaClass
addChild(bola); // añade el objeto al escenario[/as3]

Dándole un comportamiento a nuestra clase

Si queremos dotar de comportamiento a nuestro clip, podemos escribir la clase nosotros en vez de dejar que lo haga automáticamente el compilador. De esta manera, tendremos el aspecto lógico y gráfico ligados.

Por ejemplo, vamos a hacer que nuestra bola, cada x segundos, desaparezca de su posición y aparezca en una nueva. Para ello creamos una nueva clase llamada BolaClass en la misma carpeta que tenemos el fla. El código podría ser algo así:

[as3]package {
import flash.display.MovieClip;
import fl.transitions.Tween;
import fl.transitions.TweenEvent;
import fl.transitions.easing.Strong;
import flash.utils.Timer;
import flash.events.TimerEvent;

public class BolaClass extends MovieClip{

private var _ancho:int = 300;
private var _alto:int = 150;

private var _tweenAlpha:Tween;
private var _tweenX:Tween;
private var _tweenY:Tween;

function BolaClass(){
alpha = 0;
// Crear un delay aleatorio para comenzar
var retardo:Number = Math.random() * 2000;
var t:Timer = new Timer(retardo, 1);
t.addEventListener(TimerEvent.TIMER_COMPLETE, comenzar);
t.start();
}

private function comenzar(e:TimerEvent):void
{
aparecer(null);
}
private function aparecer(e:TweenEvent):void
{
x = Math.random() * _ancho;
y = Math.random() * _alto;
var tiempo:Number = 1 + Math.random() * 3;
_tweenAlpha = new Tween(this, “alpha”, Strong.easeOut, 0, 1, tiempo, true);
_tweenX = new Tween(this, “scaleX”, Strong.easeOut, 0, 1, tiempo, true);
_tweenY = new Tween(this, “scaleY”, Strong.easeOut, 0, 1, tiempo, true);
_tweenAlpha.addEventListener(TweenEvent.MOTION_FINISH, desaparecer);
}
private function desaparecer(e:TweenEvent):void
{
var tiempo:Number = 1 + Math.random() * 2;
_tweenAlpha = new Tween(this, “alpha”, Strong.easeIn, 1, 0, tiempo, true);
_tweenX = new Tween(this, “scaleX”, Strong.easeIn, 1, 0, tiempo, true);
_tweenY = new Tween(this, “scaleY”, Strong.easeIn, 1, 0, tiempo, true);
_tweenAlpha.addEventListener(TweenEvent.MOTION_FINISH, aparecer);
}
}
}[/as3]

Una vez lista la clase, probemos a crear varias bolas en el escenario, por programación o arrastrándolas directamente desde la biblioteca. Ya tenemos nuestro clip con su comportamiento específico:

This movie requires Flash Player 9

Descargar ejemplo

Cabe resaltar, que ahora que tenemos nuestra clase, si abrimos el panel de vinculación y le damos al check verde veremos este mensaje:

The definition for this class was found at [ruta de la clase]

en vez del mensaje anterior donde nos decía que generaría la clase él mismo. Y si clicamos en el lápiz Flash nos abrirá el .as en el IDE.

Utilizando nuestra propia clase base

Como hemos dicho antes, al margen de los símbolos por defecto, podemos utilizar cualquier tipo de clase como base (siempre que tenga coherencia). Por ejemplo, en nuestro ejemplo de la bola, la clase base podría haber sido perfectamente Sprite.

Pero la herencia no se limita sólo a las clases nativas de Flash, sino que pueden ser propias. Esto es útil cuando queremos dotar de comportamiento a múltiples objetos.

Sobre el ejemplo de la bola, imaginemos que queremos que otros objetos como un cuadrado y un triángulo tengan su comportamiento (cambiar de posición mediante un fundido). Una opción sería generar una clase para cada objeto. ¿Pero qué pasa si tengo 20 tipos de objetos diferentes? ¿Y si en vez de ser una clase sencilla son cientos de líneas? En este caso es más útil aislar el comportamiento y que lo utilicen todos los objetos. Vamos a verlo:

  1. Creamos una clase: Fundido.as
    El código es el mismo que el utilizado en BolaClass, así que sólo tenemos que cambiar el nombre de la clase y el nombre del constructor.
  2. Igual que hicimos con la bola, creamos dos MovieClips más, un cuadrado y un triángulo.
  3. En el panel de vinculación, le damos los siguientes nombres respectivamente: BolaClass, CuadradoClass y TrianguloClass (las clases no deben existir, dejamos que las cree el compilador)
  4. En el campo de la clase base, ponemos Fundido.
  5. Añadimos al escenario los clips y probamos la película.

This movie requires Flash Player 9

Descargar ejemplo

Tipo de símbolos para exportar

Para acabar, vamos a ver los tipos de símbolos que utiliza Flash CS3. Decíamos que el parámetro Base class viene dado por el tipo de símbolo que utilizamos. Cuando convertimos a símbolo, Flash nos da estas opciones:

  • MovieClip – utiliza la clase base flash.display.MovieClip
  • Button – utiliza la clase base flash.display.SimpleButton
  • Graphic – no se puede utilizar de manera dinámica, por lo tanto no está disponible para exportar.

Además, a través de la opción de importar, podemos generar dos tipos más de contenido para utilizar de manera dinámica:

  • Imágenes – hereda de flash.display.BitmapData
  • Audio – hereda de flash.media.Sound

Tipo de símbolos que se pueden usar en la librería de manera dinámica

El funcionamiento es exactamente igual para todos: definimos un nombre de clase y mediante new la instanciamos. La única clase base que tiene una peculiaridad es BitmapData. Si le damos a nuestra imagen el nombre ImagenClass y probamos a crear una mediante new veremos este error:

1136: Incorrect number of arguments.  Expected 2.

Esto es debido a que el constructor de esta clase espera dos parámetros: anchura y altura. Aunque en teoría debería ser la anchura y altura de la imagen, conque le pasemos un número (negativo, decimal, con 20 cifras…) es suficiente. El compilador sobreescribe con los valores correctos (sí, no tiene mucho sentido).
El código sería similar a este:

[as3]var img = new ImgClass(0,0); // Instanciamos una imagen de nuestra librería
var bmp = new Bitmap(img); // Creamos un objeto Bitmap para contenerla
addChild(bmp); // Lo añadimos a la lista de visualización
[/as3]

Resumiendo

Con la llegada de AS3 todo gana en coherencia, y no sólo en cuanto a código se refiere. También ha obligado a Flash CS3 a cumplir en este sentido, y ahora utilizar nuestros clips de biblioteca de manera dinámica es tan fácil como darle un nombre de clase (que además no estamos obligados a crear) e instanciarla mediante el operador new.

Además, con la posibilidad de utilizar una clase base para nuestros objetos, gana fuerza la opción de herencia frente composición, aunque en muchos casos seguirá siendo preferible ésta última.

Información del artículo

Post publicado el 21 de December de 2007 a las 21:01 por llops

Categorias: Artículos

Etiquetas: , , , , ,

Comparte

6 comentarios

  • Quiza

    Que tal dani !!

    no manches interesantisimo tu plublicacion, lo estuve leyendo con calma y esta profundo muy bien explicado , con la llegada de Flash CS3 todo va cambiar , ahora si como decian en el gran hermano, “las reglas cambian” .

    Yo me despegue de flash, de todo de hecho !!!! ahora me estoy volviendo a meter y pues bueno, AS 2.0 me quedé totalmente desconectado, no tengo ni la mas remota idea, pero ahora que ya estoy regresando y pues planeo meterme de llego (geek) ñ_ñ pues será de lleno al AS 3.0 ahorita estoy bajando el trial para realizar varios ejemplos y pues me inscribiré a lynda.com para meterme mas ya que no encuentro mucha documentacion de esta renovada plataforma.

    Dani gracias por compartir un poco de tus granades conocimientos !!

    Quiza

  • willow

    Hola…
    Enhorabuena por tus “clases magistrales” estoy empezando con AS3 y estos 3 tips tuyos me han ayudado muchisimo, he avanzado mas en 2 horas que en dos dias leyendo sobre AS3.
    Continua asi, somos muchos los que queremos aprender AS3 y con tips como los tuyos se consigue.
    Saludos

  • Eisen

    Genial, lástima que este sea el ultimo artículo de la seríe :'(

  • Geniales los tres artículos. Enhorabuena.

  • No termina de convencerme tanto. Desaparece el attachMovie, ¡pues vaya faena!, en absoluto me ha parecido nunca que usara una sintaxis engorrosa. Lo que sí es engorroso es tener que usar la clase getDefinitionByName() del paquete flash.utils para poder cargar dinámicamente un objeto pasándole como argumentos unas propiedades.
    Y mucho más, tener que usar la clase getDefinition() que ni se sabe en qué diablos de paquete se encuentra, cuando cargamos objetos de otros swf diferentes.
    ¿La optimización del código no significa escribir menos líneas que hagan lo mismo?.
    Pues lo que antes hacíamos con una sola linea, ahora nos cuesta doce.
    Salu2
    `8¬}
    Juan Muro

  • he terminado el ultimo de los III articulos y me a ayudado de mucho les agradesco por estos buenos aportes..