Lista de Visualización en ActionScript 3, algo de lo nuevo.
Para comenzar con este tema hay que aclarar que el modelo de renderización de ActionScript 3.0 y Flash Player 9 es muy diferente a las versiones anteriores.
Anteriormente toda película SWF contaba con un MovieClip raíz, llamado escenario o _root desde el código. Estos MC podían contener MC hijos, y a su vez estos tener otros MC hijos dentro. El concepto de profundidad se usaba para controlar el orden de renderización o dibujo de estos elementos para dar la apariencia de estar "encima" o "debajo" de otros elementos.
Antes se usaban metodos muy conocidos como createEmptyMoviClip(), attachMovie(), duplicateMovieClip(), para ordenar y crear estos MC. Siempre que se creaba un nuevo MC este aparecia por encima de los ya existentes. No podían ser movidos a lugares diferentes dentro de las jerarquías existentes, sino que se debían destruir y crear nuevamente. por ejemplo si yo tenia un MC dentro de otro llamado "objeto1" no podia moverlo a un MC llamado "objeto2". Debía borrarlo y volver a crearlo dentro del otro MC.
El nuevo sistema de render sigue siendo jerárquico, pero es mucho mas flexible y simple al momento de rendriza. Este nuevo modelo o sistema se centra en lo que se llama "Lista de Visualización" que se encuentra centrado en la clase flash.display.
Esta lista de visualización contiene todos los objetos que hay en nuestro SWF, por lo que cualquier objeto que no se encuetre en esta lista no sera renderizado en nuestra película.
Esta jerarquía se separa en 3 tipos de objetos:
El escenario: es un objeto raíz único de cada película, el cual contiene un solo hijo, la clase de aplicación principal del SWF. Se puede acceder a traves de la propiedad stage.
Contenedores del objeto de visualización: como su nombre lo indica es el objeto encargado de contener los objetos de visualizacion. El escenario sería uno de estos objetos, como también los conocidos MovieClip y el nuevo Sprite. Vale aclarar que si un Contenedor es eliminado, todos sus hijos se eliminan también.
Objetos de visualización: Algunas clases funsionan tanto como objetos de visualización como contenedores, como puede ser el caso del MovieClip, quein contiene pero a la vez puede representarse visualmente.
Hay otras clases como el caso del TextField, que unicamente funsionan como objetos visuales (o sea no pueden contener nuevos objetos como hijos).
una vez explicado esto vamos a pasar a lo que a la mayoría les interesa, los ejemplos.
Como podemos añadir un elemento a nuestra lista de visualización?
La solución es utilizar los nuevos metodos addChild() y addChildAt().
-
var textoHola:TextField = new TextField();
-
textoHola.text = "Hola Mundo!";
-
addChild(textoHola)
Con este ejemplo estamos creando un elemto de texto (TextField) que nos dice "Hola Mundo!". Si no escribiriamos la última linea, el texto no se mostraria en nuestra película, ya que no fue guardado en la lista de visualización. Por lo tanto, hubiera sido creado en memoria, pero no renderizado.
En este ejemplo estamos agregando el elemento a un Conetenedos, que seria el escenario en si. Tambien podriamos crear un Contenedor (MovieClip, Sprite) e incluir el texto ahi dento.
-
var textoHola:TextField = new TextField();
-
textoHola.text = "Hola Mundo!";
-
-
var contenedor:Sprite = new Sprite();
-
addChild(contenedor)
-
-
contenedor.addChild(textoHola)
De esta forma tenemos un contendor y un texto como hijo del mismo.
Otro cambio importante es el orden de nuestros elemntos. La lista de visualización, como su nombre lo indica es una lista como cualquier Array. O sea tiene ordenados los elemntos de la posición 0 a la que sea necesario. Por lo tanto si yo creo dos circulos y los agrego al escenario ocuparían las posicones 0 y 1, y si creo un tercero ocuparía la posición 2.
Ahora bien, si yo quisiera que el nuevo circulo este entre el 0 y 1 como hago?. Ahí entra addChildAt().
Veamos un ejemplo y luego lo explico:
-
var rojo:Shape = createCircle(0xff0000, 10);
-
rojo.x = 10;
-
rojo.y = 20;
-
var verde:Shape = createCircle(0x00ff00, 10);
-
verde.x = 15;
-
verde.y = 25;
-
var azul:Shape = createCircle(0x0000ff0, 10);
-
azul.x = 20;
-
azul.y = 20;
-
-
// hasta acá creamos en memoria los circulos, pero no son renderizados.
-
-
addChild(rojo);
-
addChild(azul);
-
-
// acá ingresamos en la lista de visualización el circulo rojo y azul, por lo tanto rojo es 0 y azul es 1.
-
-
addChildAt(verde, 1);
-
-
// por último ingresamos en la lista a circulo verde, pero en la posición 1 como se ven en los parametros, por lo que desplaza al circulo azul, que estaba en 1 a la posición 2.
-
-
// createCircle sería un metodos para dibujar los circulos
-
function createCircle (color:uint, radio:Number):Shape{
-
var shape:Shape = new Shape();
-
shape.graphics.beginFill(color);
-
shape.graphics.drawCircle(0,0,radio);
-
shape.graphics.endFill();
-
return shape;
-
}
Como se explica en el código cuando un elemento es ingresado en una posición ya utilizada, corre todos los demás elemento una posición hacia "arriba". Esto es muy util y bueno, ya que no es necesario como antes poner un elemento en un nivel 1 y otros en 20, para dejar espacio por las dudas en el medio. Por lo tanto de esta forma tenemos la lista con las posicones necesarias y ordenadas pefectamente sin numeros salteados.
Para eliminar un objeto se utiliza el metodo removeChild() y removeChildAt() de una manera muy simple.
-
//creamos el elemento.
-
var textoHola:TextField = new TextField();
-
textoHola.text = "Hola Mundo!";
-
addChild(textoHola);
-
-
// lo eliminamos
-
removeChild(textoHola);
Obviamente si ejecutamos este código, no se verá nada, ya que el elemento se crea y elimina en el momento.
Con removeChild() debemos pasarle como parametro el nombre del objeto creado. En cambio con removeChildAt(), lo que pasamos como parametro es la posición dentro de la lista de visualización. Por ejemplo:
-
//creamos los elementos.
-
var texto1:TextField = new TextField();
-
texto1.text = "Hola Mundo 1!";
-
addChild(texto1);
-
-
var texto2:TextField = new TextField();
-
texto2.text = "Hola Mundo 2!";
-
addChild(texto2);
-
-
// eliminamos el primer texto
-
removeChildAt(0);
Ahora bien veamos como podemos mover un elemento de un lugar a otro. Esto es muy simple y se hace con el metodo setChildIndex(). Y con la ayuda de los metodos getChildIndex() y getChildAt() para saber la posción de los elementos. Por ejemplo:
-
var rojo:Shape = createCircle(0xff0000, 10);
-
rojo.x = 10;
-
rojo.y = 20;
-
var verde:Shape = createCircle(0x00ff00, 10);
-
verde.x = 15;
-
verde.y = 25;
-
var azul:Shape = createCircle(0x0000ff0, 10);
-
azul.x = 20;
-
azul.y = 20;
-
-
addChild(rojo);
-
addChild(azul);
-
addChild(verde);
-
-
//ahora movemos el circulo verde atras de todo
-
setChildIndex(verde, 0);
-
-
// createCircle sería un metodos para dibujar los circulos
-
function createCircle (color:uint, radio:Number):Shape{
-
var shape:Shape = new Shape();
-
shape.graphics.beginFill(color);
-
shape.graphics.drawCircle(0,0,radio);
-
shape.graphics.endFill();
-
return shape;
-
}
De esta forma el ciruclo verde que estaba adelante de todo pasa al fondo, desplazando todos los demás una posición hacia adelante.
Ahora bien si queremos moverlo a la posción del medio, o sea del circulo azul y no sabemos el número de posición, podemos hacer lo siguiente:
-
var rojo:Shape = createCircle(0xff0000, 10);
-
rojo.x = 10;
-
rojo.y = 20;
-
var verde:Shape = createCircle(0x00ff00, 10);
-
verde.x = 15;
-
verde.y = 25;
-
var azul:Shape = createCircle(0x0000ff0, 10);
-
azul.x = 20;
-
azul.y = 20;
-
-
addChild(rojo);
-
addChild(azul);
-
addChild(verde);
-
-
//ahora movemos el circulo verde atras de todo
-
setChildIndex(verde, getChildIndex(azul));
-
-
// createCircle sería un metodos para dibujar los circulos
-
function createCircle (color:uint, radio:Number):Shape{
-
var shape:Shape = new Shape();
-
shape.graphics.beginFill(color);
-
shape.graphics.drawCircle(0,0,radio);
-
shape.graphics.endFill();
-
return shape;
-
}
Donde getChildIndex(azul) nos devolvería el número de posición del elemento llamado azul.
Nos quedaría ver el metodos getChildAt() el cual nos devuelve a traves de un número pasado como parametro el nombre de un elemnto.
Podemos usarlo en un ejemplo donde pasamos el elemento que esta atras de todo para adelante de todo. Veamos:
-
var rojo:Shape = createCircle(0xff0000, 10);
-
rojo.x = 10;
-
rojo.y = 20;
-
var verde:Shape = createCircle(0x00ff00, 10);
-
verde.x = 15;
-
verde.y = 25;
-
var azul:Shape = createCircle(0x0000ff0, 10);
-
azul.x = 20;
-
azul.y = 20;
-
-
addChild(rojo);
-
addChild(azul);
-
addChild(verde);
-
-
//ahora movemos el circulo rojo adelante de todo
-
setChildIndex(getChildAt(0), numChildren -1);
-
-
// createCircle sería un metodos para dibujar los circulos
-
function createCircle (color:uint, radio:Number):Shape{
-
var shape:Shape = new Shape();
-
shape.graphics.beginFill(color);
-
shape.graphics.drawCircle(0,0,radio);
-
shape.graphics.endFill();
-
return shape;
-
}
En este ejemplo a trasves de getChildAt(0) obtenemos el nombre "rojo", el cual movemos a la ultima posición, la cual obtenemos con el metodos numChildren - 1 (ya que la primera es 0).
Es un tema muy extenso que intente resumirlo lo mejor posible, así que espero les sirva un poco esto y cualquier duda escriban en los comentarios.
Fuente de inspiración: Libro ActionScript 3.0 para desarrolladores Flash.


Escrito por: WeeDo en 



Martin dijo:
willow001 dijo:
En primer lugar enhorabuena por tu trabajo.
Cuando pruebo tus ejemplos me tira un error de que la funcion no devuelve un valor, en AS3 cuando una funcion devuelve un valor hay que añadirle la sentencia return, por ello creo que a la funcion createCircle habria que añadirle la linea
return(shape);
Saludos
WeeDo dijo:
Gracias por la corrección!