Comunidad de diseño web y desarrollo en internet online

Flash+AS3. Array de Sprites. Como vaciarlo?

Citar            
MensajeEscrito el 18 May 2012 11:07 am
Hola, tengo una aplicación Flash que corre sola con el flashplayer standalone, nada de web. Todo el codigo está en AS3.

Mi problema es que en una parte de la aplicación he reutilizado un código de un ejemplo de programación AS3 para hacer una pizarra en la que se pueda pintar con el dedo. El caso es que funciona pero a veces se queda la aplicación colgada (o parada, no se) siempre en el mismo lugar, cuando se borra la pizarra para volver a empezar.

Este código que copié del ejemplo lo modifiqué para que se ejecute de acuerdo a mis necesidades pero las partes importantes permanecen tal cual:

Código ActionScript :

var lines:Array = new Array();
var controlpizarra:Array = new Array();
public function pintar():void {
   humano = 0;
   color = color_piza;
   thickness = grosor_piza;
   trace(tracesOk + "pintando...");
   if (sema_barra == 1) {
      dibujaTimer();
   }
   addEventListener(TouchEvent.MOUSE_DOWN, downEvent, false, 0, true);
   addEventListener(TouchEvent.MOUSE_UP, upEvent, false, 0, true);
   addEventListener(Event.ENTER_FRAME, updater, false, 0, true);   
}
//Actuliza/dibuja las líneas dibujadas.
// tuioobj es el blob - se puede ver como se le llama con una petición usando el id del blob.
function updater(e:Event):void {
   if (sema_barra == 1) {
      calculaTimer(intervalo,empiezaPizarra,esperaPizarra);
   }
   for (var i:uint = 0; i < blobs.length; i++) {
      var tuioobj:TUIOObject=TUIO.getObjectById(blobs[i].id);
         removeBlob(blobs[i].id);
      } else if (parent != null) {
         lines["line"+blobs[i].id].graphics.lineTo(tuioobj.x, tuioobj.y);
      }
   }
}
//Hay un dedo en la pantalla de la pizarra
function downEvent(e:TouchEvent):void {
   var curPt:Point=parent.globalToLocal(new Point(e.stageX,e.stageY));
   addBlob(e.ID, curPt.x, curPt.y);   
   e.stopPropagation();   
   humano = 1;
}
//Acaba de retirarse un dedo de la pantalla de la pizarra
function upEvent(e:TouchEvent):void {
   removeBlob(e.ID);
   e.stopPropagation();
}
//Añadimos un blob al array, creamos el sprite y lo visualizamos
function addBlob(id:Number, origX:Number, origY:Number):void {
   blobs.push( {id: id, origX: origX, origY: origY, myOrigX: x, myOrigY:y} );
   var line:Sprite = new Sprite();
   lines["line"+id] = line;
   lines["line"+id].graphics.lineStyle(thickness, color);
   lines["line"+id].graphics.moveTo(origX, origY); 
   addChildAt(lines["line"+id],1);
   trace(tracesOk + tracesOk + "nueva linea: lines[line" + id + "]");
   controlpizarra.push(id);
   }
//Elimina los blobs del array
function removeBlob(id:Number):void {
   for (var i=0; i < blobs.length; i++) {
      if (blobs[i].id==id) {
         blobs.splice(i, 1);
   return;
      }
   }
}
//Elimina la barra y las "pintadas" de la pantalla y vacia el array de lineas
function volvere():void {
   trace(tracesOk + "...dejamos de pintar");
   removeEventListener(TouchEvent.MOUSE_DOWN, downEvent);
   removeEventListener(TouchEvent.MOUSE_UP, upEvent);
   removeEventListener(Event.ENTER_FRAME, updater);
   if (sema_barra == 1) {
      terminaTimer();
   }
   for (var l:uint=0; l < controlpizarra.length ; l++) {
      removeChild(lines["line"+controlpizarra[l]]);
      delete lines["line"+controlpizarra[l]];
   }
   controlpizarra.length = 0;                                    
}

Ya se que es un poco críptico y que hace uso de librerías "externas" en este caso "TouchEvent.MOUSE_DOWN/UP" que lo que hacen es recibir información de un sistema de pantalla táctil que no tiene nada que ver con lo que ocurre ya que la parte táctil funciona sin problemas.

Lo que me ocurre es que en estas líneas:

Código ActionScript :

   var line:Sprite = new Sprite();
   lines["line"+id] = line;

Entiendo que se está creando un SPRITE y se está "metiendo" en el ARRAY llamado "lines", esto ocurre tantas veces como veces se mueva un dedo por la pantalla, con lo que en el uso que le doy a este código puede ser entre ninguna y 40 o 50 veces. En modo debug veo que el array "lines" se va llenando con estos sprites pero el "length" del array siempre es "0" y eso es lo que no entiendo porque no soy capaz de borrar ninguno de esos sprites y cada vez que la aplicación pasa por la pizarra el array se va llenando y llenando.

He intentado vaciarlo con "splice" y con "delete" pero, aunque no da ningún error de compilación ni ejecución, el array no se vacía en absoluto, se puede ver al final:

Código ActionScript :

for (var l:uint=0; l < controlpizarra.length ; l++) {
      removeChild(lines["line"+controlpizarra[l]]);
      delete lines["line"+controlpizarra[l]];
}
controlpizarra.length = 0;

El removeChild sí funciona y elimina las "pintadas" de la pantalla, pero el delete (he probado con splice y lo mismo) no funciona en absoluto.

Se que es un tanto largo y farragoso, pero se reduce a si alguine me puede decir como festionar este array de sprites y vaciarlo o eliminarlo y lo creo de cada vez o lo que sea.

Muchas gracias de antemano.
Paris

Por jparis

13 de clabLevel



 

España

firefox
Citar            
MensajeEscrito el 18 May 2012 12:56 pm
A ver si entiendo, haces

trace(controlpizarra.length)
controlpizarra.splice(0)
delete controlpizarra
trace(splice.length)

¿Y te sigue saliendo el largo del array?

Jorge

Por solisarg

BOFH

13669 de clabLevel

4 tutoriales
5 articulos

Genero:Masculino   Bastard Operators From Hell Premio_Secretos

Argentina

firefox
Citar            
MensajeEscrito el 18 May 2012 01:15 pm
No, ese array si se comporta "normalmente", el que se comporta de forma "anormal" es lines (que se ha creado previamente con un var lines:Array = new Array())

var line:Sprite = new Sprite();
lines["line"+id] = line;
lines["line"+id].graphics.lineStyle(thickness, color);
lines["line"+id].graphics.moveTo(origX, origY);
addChildAt(lines["line"+id],1);
controlpizarra.push(id);

Uso controlpizarra para guardar todos los ID de los elementos (sprites) de lines ya que no soy capaz de sacarlos de lines, pero necesito deshacerme de lines o, al menos, vaciarlo completamente y no me sale y, ah, tenga los sprites que tenga, el array lines siempre da un length de 0, incluso viéndolo en el debug se puede comprobar que tiene x elementos y el length está a 0.

Gracias por la ayuda.

Por jparis

13 de clabLevel



 

España

firefox
Citar            
MensajeEscrito el 18 May 2012 01:17 pm
Entonces no pongas esto dentro del loop

delete lines["line"+controlpizarra[l]];

Pon lo mismo que te puse antes (cambiando el array, claro) pero fuera del loop

Jorge

Por solisarg

BOFH

13669 de clabLevel

4 tutoriales
5 articulos

Genero:Masculino   Bastard Operators From Hell Premio_Secretos

Argentina

firefox
Citar            
MensajeEscrito el 18 May 2012 01:26 pm
Una captura de pantalla del debug para que veas el lines con 2 elementos (sprites) y el length a 0:

¿?

Por jparis

13 de clabLevel



 

España

firefox
Citar            
MensajeEscrito el 18 May 2012 01:28 pm
Ponlo asi

Código ActionScript :

for (var l:uint=0; l < controlpizarra.length ; l++) {
      removeChild(lines["line"+controlpizarra[l]]);
}
trace("Largo antes "+lines.length)
lines.splice(0)
delete lines
trace("Largo despues "+lines.length)


¿Que sale en el trace?

Esta linea que sigue no tiene sentido porque el lenght es read-only

controlpizarra.length = 0;

Jorge

Por solisarg

BOFH

13669 de clabLevel

4 tutoriales
5 articulos

Genero:Masculino   Bastard Operators From Hell Premio_Secretos

Argentina

firefox
Citar            
MensajeEscrito el 18 May 2012 01:42 pm
Me tira un error de compilador en la linea de "delete lines":

1189: Attempt to delete the fixed property lines. Only dynamically defined properties can be deleted.

Por jparis

13 de clabLevel



 

España

firefox
Citar            
MensajeEscrito el 18 May 2012 01:50 pm
Ah, entonces es porque lo declaras como propiedad de la clase (sorry, no me lei entero el primer larguísimo POST) ... entonces haz solo el splice y traza el largo, te debería dar cero

Jorge

Por solisarg

BOFH

13669 de clabLevel

4 tutoriales
5 articulos

Genero:Masculino   Bastard Operators From Hell Premio_Secretos

Argentina

firefox
Citar            
MensajeEscrito el 18 May 2012 01:55 pm
Ya lo he hecho y lo que ocurre es que, como te contaba en los post anteriores el trace del length da 0 en los dos casos, antes y después del splice, sin embrago el array contiene elementos tal y como puedes ver en la captura de pantalla...

Estoy hecho un lío con esto...

Por jparis

13 de clabLevel



 

España

firefox
Citar            
MensajeEscrito el 18 May 2012 02:01 pm
Ok, revisando un parte de tu primer POST veo que no es un array, es un objeto (indice alfanumerico = objeto con propiedades)
Usa

Código ActionScript :

var line:Sprite = new Sprite();
lines.push(line);
line.graphics.lineStyle(thickness, color);


¿Necesitas realmente el array lines? ¿Por que indices alfanuméricos?

Jorge

Por solisarg

BOFH

13669 de clabLevel

4 tutoriales
5 articulos

Genero:Masculino   Bastard Operators From Hell Premio_Secretos

Argentina

firefox
Citar            
MensajeEscrito el 18 May 2012 02:08 pm
Uffff!!!

Tengo que marcharme a llevar a mi hijo a natación.

Retomo en unas horas.

Gracias por el esfuerzo, espero contar contigo para terminar esto.

Gracias de nuevo

Por jparis

13 de clabLevel



 

España

firefox
Citar            
MensajeEscrito el 18 May 2012 08:05 pm
Ya estoy de vuelta!

No entiendo lo de "objeto". Lines se define al principio como un array:

var lines:Array = new Array()

de ahí el que siempre he pensado que es un array y no entendía (ni entiendo todavía) como puede contener "cosas" y su length ser 0.

Por otra parte me dices si necesito el array lines... Hombre... Como decía al principio, copié este código de un ejemplo de pizarra para pintar con el dedo en un sistema sensible al tacto y el que lo programó, lo hizo así, no se los detalles, probablemente haya muchas otras maneras de hacerlo, pero esta es la que tengo y, además, funciona bien, lo único que no funciona bien es lo que he añadido porque en el ejemplo simplemente se pintaba ad infinitum y yo necesitaba poder borrar para poder empezar a pintar de nuevo.

Lo de los indices alfanuméricos yo ya lo pensé en su momento, ¿por qué este tío le añade "line" al ID de cada sprite o lo que sea?, ¿por qué no utilizar sólo el ID?, supongo que habrá una razón, pero a mí se me escapa...

Los cambios que me propones no funcionan, se desmorona todo el invento...

Por jparis

13 de clabLevel



 

España

firefox
Citar            
MensajeEscrito el 18 May 2012 08:30 pm
Ok, como suele ocurrir, tendrás que entenderlo para poderlo modificar. Si no puedes usar numérico, será porque está usando la referencia en algún otro lado, dale vueltas.

Jorge

Por solisarg

BOFH

13669 de clabLevel

4 tutoriales
5 articulos

Genero:Masculino   Bastard Operators From Hell Premio_Secretos

Argentina

firefox
Citar            
MensajeEscrito el 18 May 2012 09:11 pm
No me he explicado bien, entiendo perfectamente como funciona todo el código, me llevó su tiempo, pero lo engo controlado, lo que no entiendo es esto del "objeto", si me lo pudieras explicar me harías un gran favor.

Por otro lado, respondiendo a lo que me dices, no, lo de añadirle "line" al ID no lo utiliza par nada en otro sitio, si lo hace es por que es necesario o porque le pareció así más bonito. Pregunta: ¿Si le quieto todos los "lines" y el índice pasa a ser numérico, deja de ser un "objeto" y pasa a ser un array o qué?

Gracias

Por jparis

13 de clabLevel



 

España

firefox
Citar            
MensajeEscrito el 18 May 2012 09:55 pm
Efectivamente, al tener índice alfanumérico lo convierte a objeto. Aquí una pequeña demo que puedes copiar y pegar en una peli nueva:

Código ActionScript :

var array1:Array = new Array()
array1[0] = "Uno";
array1[1] = "Dos";
var array2:Array = new Array()
array2["str"+0] = "Uno";
array2["str"+1] = "Dos";

trace(array1.length)
trace(array2.length)
trace(array1[0])
trace(array2.str0)


Al ser convertido a objeto, las propiedades se acceden por nombre, no por indice.
Jorge

Por solisarg

BOFH

13669 de clabLevel

4 tutoriales
5 articulos

Genero:Masculino   Bastard Operators From Hell Premio_Secretos

Argentina

firefox
Citar            
MensajeEscrito el 18 May 2012 10:14 pm
OK, tenía entendido que a esto se le llama "array asociativo", según me dices entiendo que se usa en mi caso para poder guardar los Sprites con un nombre e ID que no tengan nada que ver con un índice (por ejemplo que no empiecen desde cero), lo que no acabo de entender es por qué la propiedad length da 0 aunque en array (bueno, el objeto, o como sea) no esté vacio...

Y otra pregunta al hilo, ¿existe algún modo de eliminar estos objetos o como se llamen?, porque para meter los Sprites usa:

lines["line"+id] = line

Pero, ¿y para quitarlos?

Por jparis

13 de clabLevel



 

España

firefox
Citar            
MensajeEscrito el 18 May 2012 11:22 pm
Bueeeeeno, voy avanzando gracias a tus respuestas... Acabo de leerme la referencia de Adobe AS3 e indica que NO es una buena práctica utilizar el constructor de Array para crear arrays asociativos, que es mejor usar el constructor de Object. Además dice que si usas el constructor de Array (como es el caso) no funcionan ni las propiedades ni los métodos de la clase Array, de ahí que el length de siempre 0 y que no se pueda eliminar ningún índice ni nada ya que ningúnmétodo ni propiedad de la clase Array funcionará.
Ahora voy a mirar si lo puedo covertir a clase Object y supngo que existirá algún método para eliminar elementos del Object, digo yo...

Gracias por darme la caña, ya estoy pescando... Ahora sólo me falta que me ayudes con el cebo y sacaré una buena pescata :-)

GRACIAS

Por jparis

13 de clabLevel



 

España

firefox
Citar            
MensajeEscrito el 19 May 2012 09:39 am
Ya me estoy rayando, pero pongamos esto:

Código ActionScript :

var lines:Object = new Object();
                       |
var line:Sprite = new Sprite();
lines["line"+id] = line;
lines["line"+id].graphics.lineStyle(thickness, color);
lines["line"+id].graphics.moveTo(origX, origY);
addChildAt(lines["line"+id],1);
                        |
else if (parent != null)
        {
   lines["line"+blobs[i].id].graphics.lineTo(tuioobj.x, tuioobj.y);
        }
                        |
for (var l:uint=0; l < controlpizarra.length ; l++)
        {
   removeChild(lines["line"+controlpizarra[l]]);
   delete lines["line"+controlpizarra[l]];
        }
   controlpizarra.splice(0);
   lines.splice(0);

¿Debería de funcionar? Es que no estoy seguro de si puedo llamar a los contenidos del objeto igual que se llama a los de un Array, con los []. En caso de querer hacerlo con los puntos, en plan:

delete lines."line"+controlpizarra[l];

¿Sería más correcto? ¿La variable controlpizarra se substituiría adecuadamente?

Creo que ya casi estoy, por mi reloj toca estar durmiendo en Argentina, yo estoy probando estas conjeturas ahora mismo, aunque sólo durante un momento, le dedicaré de nuevo tiempo por la tarde, espero saber de tí para aclararme estas dudas o para agradecerte el tiempo que te has tomado y decirte que ya lo he solucionado yo solo ;-)

Por jparis

13 de clabLevel



 

España

firefox
Citar            
MensajeEscrito el 19 May 2012 01:21 pm
Graaaaaaande!

Ya está!

Efectivamente puedo tratar el Objeto como si fuese un Array en lo de usar [] o .
Eso sí , alguna de las cosas que sí van con Arrays no van con Objetos, por ejemplo el splice(0).
Pero no lo necesito ya que con:

delete lines["line"+controlpizarra[l]]

que va dentro de un bucle, borro todo el contenido del objeto uno por uno y listo.

Ahora funciona como debiera y el Objeto con los sprites no va creicendo y creciendo cada vez que s ejecuta esta parte de la aplicación.

Lo dicho, te agradezco INFINITAMENTE el tiempo y la paciencia que te has tenido conmigo.

Por jparis

13 de clabLevel



 

España

firefox

 

Cristalab BabyBlue v4 + V4 © 2011 Cristalab
Powered by ClabEngines v4, HTML5, love and ponies.