Comunidad de diseño web y desarrollo en internet online

Manipulación múltiple de MovieClips en ActionScript 3

Este tip esta hecho, para las ocasiones en que se necesita manipular varios MovieClip similares que tenemos en nuestra película, y lo queremos hacer de manera elegante, con poco código y en ActionScript 3. Este tip es muy útil en juegos donde se necesita manipular muchos o ilimitados, Sprites y/o MovieClips.

El siguiente es un ejemplo en el que este tip, puede ser muy útil y ahorrarnos bastante tiempo.

Estaba tratando de hacer invisibles solo por código 60 MovieClips mc.visible = false; . Podía hacerlo de dos maneras. Una era colocando código en cada MovieClip this.mc.visible = false; pero eso me hacia sucio ante los ojos de Freddie (Actualmente mi profesor de ActionScript 3.0).

La segunda opción era crear una clase, y en la clase colocar this.mc.visible = false; y luego vincular uno por uno cada MovieClip a esa clase. Cosa bastante dispendiosa y ineficiente.
Dado que no quería hacerlo de ninguna de las dos maneras, solo me quedaba hacer un For. Pero en AC3 nada es tan facil como parece.

Para hacer y entender el tip hay que crear 5 formas de cualquier tipo. Cuadraditos, triangulitos bolitas, etc, pero que sean cinco. Luego a cada una de esas formas las convertimos en MovieClips con F8.

Hecho esto ya podríamos asignarle la propiedad que queremos, (en este caso será si es visible o no) a nuestros MovieClip, Lo haríamos de la siguiente manera.

Código :

for (var i:int = 0; i <= 4; i++)
{
 this.getChildAt(i).visible = false;
}

Si lo probamos veremos que desaparecen nuestros 5 MovieClips. Voy a explicar

Código :

this.getChildAt(i).visible = false;

this es nuestra película. Para explicar getChildAt(i) hay que explicar la nueva manera en la que ActionScript 3.0. muestra cualquier cosa en el escenario, ya sean vectores imágenes videos etc.

En ActionScript 3.0 dos de los objetos o clases principales son DisplayObject, DisplayObjectContainer. Cuando lei la guía de flash de Adobe, entender lo que les voy a explicar fue un infierno, viniendo de AS2. Pero luego de haberme familiarizado mas con flash y flex gracias a los dos cursos de Freddie (muy buenos por cierto. mentira), entendí bien que era eso, y ya no dolió tanto. Es mas, ahora me gusta muchísimo la forma en la que ActionScript 3, maneja los elementos gráficos, porque facilita muchísimo las cosas, y mejora muchas fallas que tenia AS2 que hacía que programar un juego de disparos y infinitos blancos fuera un tormento. Ahora con ActionScript 3 es mucho mas fácil.

Voy a tratar de explicar esto de manera sencilla y sensata y no como adobe que por tratar de explicar muy detalladamente algo, hacen jodidos de entender términos que son sencillos.

DisplayObject, es la clase principal de la que heredan todas las demás clases o objetos que se pueden visualizar en el escenario. Osea DisplayObject es el padre de
    - Bitmap = imagen
    - Shape = vector
    - MorphShape = Trasformación de vector
    - StaticText = texto estático
    - Video = pues eso
    - SimpleButton = botón simple
    - TextField = campo de texto

Todos estos son los objetos que se pueden mostrar en Flash. Pero hay un problema, ninguno de estos, pueden mostrarse si no están dentro de algo como una carpeta, caja o contenedor. Este algo se llama DisplayObjectContainer. Aunque el nombre sea complicado es algo muy sencillo de entender.

DisplayObjectContainer es como una carpeta, caja o contenedor a la que uno le mete cosas. Podría ser un Texto, una imagen un video un vector etc.

Y solo hay 4 tipos de carpeta, caja o contenedor. Estos son:
    - Loader = Cargador
    - Sprite = MovieClip sin línea de tiempo
    - MovieClip = Clip de película
    - Stage = Escenario

Estos cuatro objetos heredan de la clase DisplayObjectContainer. El más importante es Stage que es nuestro escenario y que sirve de carpeta, caja o contenedor a todo lo demás.

El otro que también es importante es Loader, que nos sirve para cargar objetos externos como una imagen o un video. Una imagen o un video no se pueden colocar (por codigo) directamente en el escenario. Tiene que estar dentro de un Loader.

Los otros dos Sprite y MovieClip son bien conocidos.

Todos estos cuatro objetos heredan las propiedades, métodos y eventos de la clase DisplayObjectContainer. Y en este caso, para nuestro ejemplo lo mas importante son los métodos. DisplayObjectContainer tiene varios métodos que nos sirven para manejar las demás cosas que hay dentro de el. por ejemplo:
addChild() nos sirve para agregar algo a la carpeta, caja o contenedor. Se

Código :

entiende mejor con un ejemplo.
// Creamos un Sprite que nos va a servir de contenedor
var contenedor:Sprite = new Sprite();
// Colocamos nuestro contenedor dentro de la película.
// pero como no tiene nada adentro, no vemos nada.
this.addChild(contenedor);
// Creamos dos campos de texto
var texto1:TextFiel = new TextFiel();
var texto2:TextFiel = new TextFiel();
// Colocamos contenido en los dos campos de texto
texto1.text = "Hola Mundo";
texto2.text = "Chao Mundo";
// Colocamos nuestros textos dentro del contenedor.
// y como el contenedor esta dentro del escenario ya podemos ver nuestros textos
contenedor.addChild(texto1);
contenedor.addChild(texto2);

De esta manera tenemos dos textos dentro de nuestro contenedor Sprite. Nuestro Sprite luce asi.

Código :

contenedor  I
                   I____texto1                                    índice 0
                   I
                   I____texto2                                    índice 1

getChildAt() es otro método, al igual que addChild(); que tienen los objetos contenedores (Loader, Sprite, MovieClip, Stage). getChildAt() nos permite acceder a cualquier cosa que tengamos dentro de nuestro contenedor. Si al código anterior le añadimos

Código :

trace(contenedor.getChildAt(0).name);

nos devuelve el nombre del objeto que esta en el indice 0, En nuestro caso seria texto1.
Si colocamos

Código :

contenedor.getChildAt(1).y = 50; 

texto2 se mueve 50 pixeles hacia abajo.
Si colocamos

Código :

contenedor.getChildAt(0).visible = false; 

Nuestro texto texto1 desaparece.
También hay otro método importante que es getChildByName(); Este método nos sirve para encontrar lo que hay dentro de un contenedor por medio del nombre. Si yo digo

Código :

contenedor.getChildByName("texto2").visible = false;

Se me desaparece el objeto que tenga como nombre texto2.

Hay una propiedad muy importante que me dice cuantos elementos hay en un contenedor. Esa propiedad es numChildren

Código :

trace (contenedor.numChildren);

En nuestro trace saldría 2, y es porque a nuestro Sprite con nombre contenedor le hemos metido dos elementos.
Para ver todos las propiedades métodos y eventos de los contenedores ir a este link

Ahora si es mas fácil entender el primer código.

Código :

for (var i:int = 0; i <= 4; i++)
{
 this.getChildAt(i).visible = false;
}

Como decía, este código nos desaparece nuestros 5 MovieClips.
Pero hay un gran problema con esto. Es muy probable que tengamos muchos mas de 5 MovieClips en nuestra películas y este código, modificaría nada mas los primeros 5 objetos que se colocaron en escena. ¿Entonces como hacemos para solo modificar nuestras 5 formas sin tocar ni modificar los otros MovieClips que no queramos?

Para eso hacemos lo siguiente. Colocamos de nombre de instancia a cada forma, un nombre en secuencia. eje. forma_1, forma_2, forma_3, forma_4, forma_5. En un juego de disparos puede ser disparo_1, disparo_2 etc. Colocarles los nombres de instancia en secuencia es vital para poder asignar las propiedades que queremos.

Hecho esto colocaremos el siguiente código:

Código :

for (var i:int = 1; i <= 5; i++){
   var referencia = this.getChildByName("forma_"+i);
   referencia.visible = false;
}

Asi, ya desaparecimos nuestras 5 MovieClips que se llamaban forma_*. y con esto ya seria suficiente. Pero el codigo anterior tiene unas limitaciones. Los nombre de los movieClips no quedar ordenados alfabéticamente. Me explico. Como lo hicimos podría quedar asi

Código :

stage (escenario) I
                         I______ forma_1            indice 0
                         I______ forma_3            indice 1
                         I______ forma_2            indice 2
                         I______ forma_5            indice 3
                         I______ forma_4            indice 4

Aca vemos que los numeros de indice, no corresponden con el orden alfabético. Esto se debe a que el numero del indice, se determina en el momento de escribir el nombre de la instancia. En la mayoría de los casos eso no es un problema, pero si tenemos 60 MovieClips y necesitamos acceder al MovieClip con el nombre forma_45 y pensamos que esta en el indice 44, no tenemos la certeza que sea asi. Tambien podriamos encontrar un MovieClip por medio del nombre, pero segun adobe, es mas rapido acceder por medio del inidice, puesto que no tiene que hacer una búsqueda. En mi caso, yo necesitaba que todos los MovieClips estuvieran estrictamente ordenados. Entonces para eso hacemos lo siguiente.

Código :

var contenedor:Sprite = new Sprite();
this.addChild(contenedor);
for (var i:int = 1; i <= 5; i++)
{
        var referencia = this.getChildByName("forma_"+i);
        contenedor.addChild(referencia);
}
for (var e:int = 0; e <= contenedor.numChildren-1; e++)
{
        contenedor.getChildAt(e).visible = false;
}

En nuestro primer for, agregamos todos los elementos que tenia el escenario con el nombre forma_+ 1 + 2 + 3 + 4 + 5. Luego los agregamos al sprite que nos sirve de contenedor llamado contenedor. de esta manera ordenamos alfabéticamente los MovieClips, ademas asi, tenemos todo mas ordenado.

En el segundo for, cogemos todos los objetos que le metimos a nuestro contenedor y le décimos que no sean visibles.

Ya con esto podemos manipular todos los MovieClips que queramos de una manera elegante y con poco código.

¿Sabes SQL? ¿No-SQL? Aprende MySQL, PostgreSQL, MongoDB, Redis y más con el Curso Profesional de Bases de Datos que empieza el martes, en vivo.

Publica tu comentario

o puedes...

¿Estás registrado en Cristalab y quieres
publicar tu URL y avatar?

¿No estás registrado aún pero quieres hacerlo antes de publicar tu comentario?

Registrate