AS3 no es difícil, y si se tiene una buena base de AS2 (o de otros lenguajes como C# o Java) el cambio no es muy doloroso. Una persona con conocimientos de programación orientada a objetos que empiece en Flex Builder un “Proyecto ActionScript” (sólo código) no tendrá muchas dificultades (evidentemente tendrá que conocer la sintaxis). En cambio, esta misma persona comenzando con Flash, tendrá que familiarizarse con conceptos como timeline o movieclip y entender la relación con el lenguaje.
El problema es que, en esta nueva versión, el programa se ha tenido que adaptar a las características OOP del lenguaje, así que también ha habido cambios que los programadores flash de toda la vida tenemos que asimilar (es muy difícil deshacerse de las viejas prácticas, y más si llevas 4 o 5 versiones del programa).
En este primer artículo vamos a ver qué significan las acciones que realizamos en el IDE de Flash desde el punto de vista de actionscript.
El Document class
Una de las novedades de CS3 es el Document class. Se trata de la clase principal asociada a una película flash, o dicho de otra manera, el punto de arranque de la aplicación. Al declarar el Document class nos ahorramos tener que meter código en el fla.
Main es la clase asociada que se encuentra en el paquete com.llops
Veamos el código de nuestra clase Main:
[as3]package com.llops
{
import flash.display.MovieClip;
public class Main extends MovieClip
{
function Main(){
}
}
}
[/as3]
Vemos como la clase está declarada con el modificador public. Esto es un requisito al estar vinculada al document class.
Si especificamos un Document class que no existe, el compilador crea una clase con dicho nombre, y si no declaramos ninguno, el compilador asigna uno de manera transparente. Así pues, todas las aplicaciones flash parten de una clase base.
La clase base debe extender de Sprite, pero si cuenta con código en algún frame o se quiere utilizar la línea de tiempo lo ha de hacer de MovieClip (realmente hay algún caso más, pero de momento nos podemos quedar con los dos principales).
Cualquier código que añadamos en un frame del timeline principal pasará a ser parte de nuestra clase. Por ejemplo, añadamos el siguiente script en el frame1 del fla:
[as3]var texto:String = “diez”;
function test():void{
var numero:int = 10;
trace(texto, numero);//Output: diez 10
}
test();
[/as3]
Al compilar el swf, la clase quedaría prácticamente de la siguiente manera:
[as3]package com.llops
{
import flash.display.MovieClip;
public class Main extends MovieClip
{
public var texto:String = “diez”;
function Main() {
test();
}
public function test():void {
var numero:int = 10;
trace(texto, numero);//Output: diez 10
}
}
}
[/as3]
Al igual que pasa con la clase, por estar declaradas en la línea de tiempo, tanto la variable como la función utilizarán el modificador public.
Llegados a este punto, hemos de quedarnos que una de las principales novedades es que, al compilar nuestra película, todo lo que hayamos hecho en el IDE se traduce a clases en AS3. Esto es válido tanto para código como para los movieclips, gráficos y botones que añadamos en el escenario.
Añadiendo movieclips manualmente al escenario
Si utilizamos flash como herramienta es porque queremos hacer uso de sus capacidades gráficas. Lo que en lenguajes como C++ llevaría horas en flash pueden ser unos pocos minutos.
Volvamos al punto en que no tenemos código en el fla y tenemos nuestra clase Main asociada al document class.
Creemos un movieclip en la biblioteca que tenga forma de cruz (MC Cruz). Arrastremos dos instancias en el escenario: una la dejaremos sin nombre de instancia y a la otra la llamaremos cruz_mc. Ahora añadamos las siguientes líneas en el constructor:
[as3]trace(getChildAt(0),getChildAt(0).name);
trace(getChildAt(1),getChildAt(1).name);
[/as3]
Al ejecutar la película, en el panel de output, veremos lo siguiente:
[object MovieClip] instance1
[object MovieClip] cruz_mc
En la película principal, existen dos objetos de la clase MovieClip (posiciones 0 y 1), con los nombres instance1 (asignado por el compilador) y cruz_mc (asignado por nosotros).
Sabiendo sus nombres no habría ningún problema en hacer lo siguiente
[as3]trace(getChildByName(“instance1”));
trace(getChildByName(“cruz_mc”));
[/as3]
devolviendo dos objetos del tipo MovieClip.
¿Pero qué pasa si probamos el siguiente código?:
[as3]trace(instance1);
trace(cruz_mc);
[/as3]
El compilador arroja el siguiente error
1120: Access of undefined property instance1
ya que no existe ninguna propiedad en la clase que responda a instance1. Aunque nos saltáramos los errores de compilación, en tiempo de ejecución, nos saldría:
Error #1065: No se ha definido la variable instance1.
Si comentamos la línea que genera error, veremos que no hay ningún problema con la segunda, y el trace de cruz_mc devuelve [object MovieClip].
Cualquier objeto que se añade manualmente al escenario se añade también a la DisplayList, por esa razón hemos podido acceder a las dos cruces mediante los métodos getChildAt y getChildByName, definidos en la clase DisplayObjectContainer y que nuestra clase hereda al extender MovieClip.
Sin embargo, al hacer trace de instance1 nos genera un error, ya que no existe realmente ninguna propiedad ni variable definida como tal, sólo es el name que utiliza internamente el compilador para manipularlo como objeto visual. Sin embargo, cruz_mc no devuelve error ya que sí existe como variable de la clase Main. Es más, si utilizamos el debugger de flash podemos encontrar un puntero en memoria reservado para cruz_mc, mientras que no hay rastro de instance1. ¿Por qué?
La razón por la que existe dicha variable es que al trabajar con AS3 en Flash CS3, el compilador provee dos mecanismos para acceder a movieclips que hayan sido creados en línea de tiempo y tengan nombre de instancia:
- Asigna el mismo nombre a una variable de la clase
- Declara dicha variable
Traducido a código, quedaría así:
[as3]package com.llops
{
import flash.display.MovieClip;
public class Main extends MovieClip
{
// Mecanismo 2:
// Declara una variable del mismo tipo (movieclip)
public var cruz_mc:MovieClip;
function Main()
{
// Mecanismo 1:
// Asigna el movieclip a la variable
// haciendo coincidir el nombre
cruz_mc = getChildByName(“cruz_mc”);
}
}
}
[/as3]
Aunque pueda parecer que el orden de los mecanismos sería más acertado al revés (mecanismo 1 crear variable y
mecanismo 2 asignarla), lo he puesto así porque el mecanismo 1 se cumple siempre, mientras que el segundo
depende de una opción que tenemos activada por defecto: Automatically declare stage instances.
Esta opción se encuentra en Publish Settings > ActionScript Settings
Si desmarcamos esta casilla y probamos a compilar obtenemos el siguiente error:
Error #1056: No se puede crear la propiedad cruz_mc en com.llops.Main.
Para que no haya problemas, debemos declarar manualmente el movieclip como variable de clase, sin olvidarnos que ha de ser pública:
[as3]public var cruz_mc:MovieClip;
[/as3]
Una vez hecho, el compilador mirará la variable, y al coincidir el nombre de instancia del movieclip con la variable, la asignará (mecanismo 1).
Si tenemos la opción marcada y además probamos a declarar la variable, el compilador nos dirá
1151: A conflict exists with definition cruz_mc in namespace internal.
debido a que ya existe.
Esto no sólo pasa con los MovieClips, sino con cualquier objeto al que le podamos dar un nombre de instancia en el escenario, como campos de texto (declarar como TextField) o botones (declarar como SimpleButton)
A priori, parece una gran utilidad que Flash CS3 declare por nosotros las variables, y más si tenemos muchísimos objetos en el escenario, pero esta solución acaba generando un código más difícil de seguir, ya que leyendo el código no sabemos de dónde salen las variables. Además, si se utiliza un editor externo como FlashDevelop o Flex Builder, marca errores o no te da las opciones de autocompletado debido a que no están declaradas.
En la práctica, esta opción me ha dado muchos más problemas que ventajas, así que recomiendo desactivar el check siempre. Al fin y al cabo, esta es una de las mejores prácticas de los lenguajes OOP, tener que declarar todo para suministrar la máxima información posible al compilador.
Resumiendo
AS2, aunque nos da una sintaxis más cercana a OOP, no deja de ser un envoltorio que acaba compilando a actionscript1. Con la llegada de AS3 tenemos realmente un lenguaje orientado a objetos, y el compilador de flash ha tenido que adaptarse. Por ello, cualquier cosa que hagamos en el IDE de Flash tiene su correspondiente transformación a AS3. Todo (código en frames, movieclips en el escenario, etc) acaba compilándose en clases.
El Document class nos proporciona una manera fácil de asociar nuestro fla con la clase principal. Sino declaramos uno, el programa lo hará de manera transparente.
Por otro lado, el compilador nos provee de mecanismos para asignar nuestros objetos en pantalla a variables de clase.
De esta manera, si una persona sin conocimientos OOP elige un proyecto AS3 en Flash, aunque sólo utilice clips de película en el escenario, animaciones e instrucciones sencillas tipo stop(), gracias a las nuevas funcionalidades del compilador, tendrá un verdadero programa orientado a objetos, aunque ni siquiera lo sepa.
[…] mantenido por llops. Experimentos y artículos entorno a la plataforma flash y as3. « Programando en AS3 desde Flash CS3 (I) […]
[…] 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 […]
Programando en AS3 desde Flash CS3 (I)…
AS3 no es difícil, y si se tiene una buena base de AS2 (o de otros lenguajes como C# o Java) el cambio no es muy doloroso. Una persona con conocimientos de programación orientada a objetos que empiece en Flex Builder un “Proyecto ActionScript” (só…
[…] hace tiempo dediqué un extenso apartado a explicar en que consiste esta opción que nos facilita Flash CS3 y cómo funciona […]
[…] AS3 desde 0 1 […]