Cristalab

Cómo eliminar objetos del escenario con removeChildAt()

Por: Juanlu_001 + 07.02.2008

Muy buenas, esta es mi primera aportación a la web de Cristalab, que tantas cosas me ha dado y que tan poco le he agradecido; ya iba siendo hora Lengua. Como he empezado recientemente a dar mis primeros pasos en ActionScript 3, me surgió un problema durante el desarrollo de una clase, y he considerado que sería útil compartirlo por si a alguien le surge la misma duda.

Como sabemos, la forma de añadir MovieClips al escenario en AS3 ha cambiado. Ahora utilizamos la función DisplayObjectContainer.addChild() para añadir un clip de película, y la profundidad (los que recuerden attachMovie sabrán a lo que me refiero) es asignada ahora automáticamente. Esto, al utilizar varios clips y querer después eliminarlos, puede llevarnos a un pequeño quebradero de cabeza.

Por ejemplo, imaginemos que queremos añadir mediante código diez MCs idénticos. Generalizando, escribiríamos algo como esto (susceptible de correcciones):

Código :


x_MC = 50;
y_MC = 100;
for (i = 0; i < 10; i++) {
var my_MC:MovieClip = new MovieClip();
my_MC.x = x_MC;
my_MC.y = y_MC;
stage.addChild(my_MC);
x_MC += 20;
}

Con lo cual tenemos 10 MCs genéricos (que según lo que he escrito aquí me parece que muchos colorines no iban a tener) en el escenario (stage). Ahora, si quisiéramos eliminarlos, podríamos escribir algo como esto:

Código :


for (i = 0; i < stage.numChildren; i++)
{
stage.removeChildAt(i);
}


Pero comprobaríamos, que sólo se eliminarían la mitad. Incluso si almacenamos en una variable el valor de stage.numChildren antes de comenzar el bucle, este producirá un error de desbordamiento. ¿Por qué?

Como los índices de profundidad son asignados automáticamente por Flash, si teníamos diez MCs de profundidades 0, 1, 2, 3, 4, 5, 6, 7, 8, 9; al eliminar el primero, se reorganizan y quedan todos como 0, 1, 2, 3, 4, 5, 6, 7, 8 y no empezando por 1 y acabando por 9, como me pensaba yo que pasaría. Sucesivamente, a medida que eliminemos los MCs del principio quedarán como 0, 1, 2, 3, 4, 5, 6, 7; 0, 1, 2, 3, 4, 5, 6; etc. Y por eso el valor de la variable i terminará o bien sobrepasando al número de objetos en el escenario o bien saliéndose de la sucesión de profundidades.

Solución: Eliminar los MCs hacia atrás.

Código :


for (i = stage.numChildren; i > 1; i--)
{
stage.removeChildAt(i - 1);
}


Es una completa estupidez, pero como dije al principio, me pareció una de esas cosas tontas que pueden tenerte más tiempo del deseable buscando un error.

Espero haber ayudado con el aporte Sonrisa.

Etiquetas actionscript_3

Comentarios | Enviar un comentario

Juanlu_001 :

[...]P.D.: Por cierto, donde pone usuario, pongan l u s e r. ¿Por qué no puedo escribir esa palabra? BOFH
Eso ya lo habia notado hace un tiempo... Imagino que debe de ser parte de la magia de Clab...


_________________
Volviendo al Tema: Buen aporte !!!...
Thumbs up
Por: M@U
Moviendo esto a tips.
Por: Freddie

M@U :

Juanlu_001 :

[...]P.D.: Por cierto, donde pone usuario, pongan l u s e r. ¿Por qué no puedo escribir esa palabra? BOFH
Eso ya lo habia notado hace un tiempo... Imagino que debe de ser parte de la magia de Clab...

Lo es..., de cualquier forma son equivalentes U_U
Por: The Fricky!
Felicidades ahora por el Tip Juanlu_001...
Thumbs up
Por: M@U
Con que eso era!!! GRACIAS! Muy pero muy útil. Gracias.
Es que yo muchas veces trate de hacer un for para borrar todo. Y ahí es donde estaba el error.
No creo que sea estúpido tu tip, por el contrario. ¿Como supiste que los Niveles se reorganizaban?
(Supongo que google)
Por: JaLeRu
No veas cómo me alegro de que te haya ayudado mi tip Muy Feliz.

Realmente lo averigüé utilizando muchos trace y razonando mucho, aunque (y esto va a quitarme muchos méritos Lengua) para responder a tu pregunta he comprobado que en la ayuda de Flash, en la descripción del método DisplayObjectContainer.removeChildAt() dice que "La posición de índice de los objetos de visualización situados por encima del elemento secundario en DisplayObjectContainer se reduce en 1".

[OffTopic]Me puse a dar saltos de alegría cuando vi mi tip en la portada de Cristalab. Apenado ¡Seguiré al pie del cañón! Lengua [/OffTopic]
Por: Juanlu_001

Juanlu_001 :

No veas cómo me alegro de que te haya ayudado mi tip Muy Feliz.

Realmente lo averigüé utilizando muchos trace y razonando mucho, aunque (y esto va a quitarme muchos méritos Lengua) para responder a tu pregunta he comprobado que en la ayuda de Flash, en la descripción del método DisplayObjectContainer.removeChildAt() dice que "La posición de índice de los objetos de visualización situados por encima del elemento secundario en DisplayObjectContainer se reduce en 1".

[OffTopic]Me puse a dar saltos de alegría cuando vi mi tip en la portada de Cristalab. Apenado ¡Seguiré al pie del cañón! Lengua [/OffTopic]

Tengo el flash en ingles, y existen cosas que no entiendo. Riendo
Por: JaLeRu
Otra solución posible sería esta, aunque no sé si preguntar numChildren en cada iteración perjudica la performance más de lo que la beneficia reemplazar un for con un while:

Código :

while (stage.numChildren > 0)
{
stage.removeChildAt (0);
}

Por: HernanRivas (logout)_blog
asi tambien se puede borrar. con while:

Código :


//---------------------------------------------------------
//stage.numChildren-1= numero de objetos en el escenario
//---------------------------------------------------------

while (stage.numChildren-1 > 0) {

   stage.removeChildAt(1);

}



y con for:

Código :


//---------------------------------------------------------
//limite = numero de objetos en el escenario
//---------------------------------------------------------
var limite:int=stage.numChildren-1;

for (var j:int=0; j<limite; j++) {
   stage.removeChildAt(1);
}


para evitar el for de reversa.

Código :


for (i = stage.numChildren; i > 1; i--)
{
stage.removeChildAt(i - 1);
}

Por: DiegoAzul
algun manual de diseño web
Por: alex_blog
Muy ilustrativo
Por: tutor29_blog
Podrian decirme donde encontrar un tutorial, les aradezco de antemano
Por: Ivan_blog

Ivan_blog :

Podrian decirme donde encontrar un tutorial, les aradezco de antemano
Aqui...
Por: M@U
También se puede usar removeChildAt(0), porque cuando borras un child de la display list, los que están arriba llenan el espacio hueco.

numFichas = new int(fichasContenedor.numChildren);
for (var i:int = 0; i < numFichas; i ) { fichasContenedor.removeChildAt(0);
}
Por: Pablo Mercado_blog
¿Hay alguna manera de editar mi comentario? ¿O de tener una vista previa antes de publicarlo? Disculpen por la sintaxis. Saludos
Por: Pablo Mercado_blog
Pablo Mercado, no te recomendaría usar fors en tareas que no requieran el uso de "i". Los whiles son más rápidos de ejecutar y requieren menos memoria (no almacenan una variable extra).

Es más, muchos compiladores (creo que el de Flash también) reemplazan los fors con whiles.
Por: HernanRivas (logout)_blog
Deja un comentario
IMPORTANTE

Recuerda ser respetuoso, no insultes a otras personas, ni uses palabrotas, hay una persona al otro lado de la pantalla.

Habla bien, NO ESCRIBAS EN MAYUSCULA TODO, no escribas como en un SMS, evita cosas como "ke", "x q" y demás abreviaciones.

Aquí funcionan las etiquetas de los foros, puedes usar [b] para negrita, [img] para las imágenes, [url] para los enlaces, etc.

Si tienes preguntas técnicas, envíalas mejor al foro.