Comunidad de diseño web y desarrollo en internet online

Instancias de Clase en AS3 sin clase externa?

Citar            
MensajeEscrito el 27 Sep 2009 06:19 am
Hola, tengo una pregunta un poco rara. Casi que en vez de una pregunta, es un reto!!!

En realidad, nunca me había enterado que uno podía cambiar el nombre de instancia a través de código, o asignarlo:

Código ActionScript :

boton.name="boton1";


Bueno. Al enterarme de esto, se me ocurrió lo siguiente: y si intentamos hacer algo como el duplcateMovieClip que tanto sonaba antes?
Por lo tanto creé una bola que tiene como nombre de clase Bola(); y que simplemente está en la biblioteca. Intento duplicarla con un Loop:

Código ActionScript :

//loop que crea 6 bolas
for (var i=1;i<6;i++){
//Crear una nueva bola
var bola:Bola=new Bola;
//asignarle un nombre a la bola creada
bola.name="bola+i";
//dar posición x a la bola creada
bola.x=80*i;
//añadir la bola al escenario
addChild(bola);
}


Funciona muy bien, y me crea en el escenario 6 bolas. Ahora lo complejo. Si creas esto, estarías creando copias de un símbolo, pero no sabía como poner un nombre de instancia cada bola para manejarla. Pensé que a través del .name le podía dar un nombre de instancia, y luego modificarlo. Pero si escribo en alguna parte, por ejemplo

Código ActionScript :

bola3.y+=100;


me dice que bola3 no existe. sin embargo un trace me dice que su nombre si es bola3. No se puede usar esta propiedad para asignar un nombre de instancia a cada bola, y después poderla manejar?

Ufff, no sé si está difícil la pregunta, pero aspiro encontrar la respuesta, me pueden ayudar? Si se encuentra, creo que se le facilita el trabajo a miles de personas, porque si lo pienso, no he visto nunca después de mucho buscar, que alguien haya aclarado esta forma. La función duplicateMoiveClip estaría viva, sin clases externas...

Un saludo. Espero su amable ayuda.
Eskombro

Por eskombro

9 de clabLevel



 

chrome
Citar            
MensajeEscrito el 27 Sep 2009 11:53 am
Eskombro, es que las cosas en AS3 han cambiado: Ya no se usa el "nombre de instancia", para controlar un MC usamos variables que hacen referencia a ese MC
Y no, la "propiedad" name NO tiene nada que ver con el nombre de instancia. La propiedad name sirve EXCLUSIVAMENTE para poder usar un getChildByName. Eso es, cuando tenemos algo como lo que has puesto

Código ActionScript :

for (var i=1;i<6;i++){ 
  var bola:Bola=new Bola; 
  bola.name="bola+i"; 
  bola.x=80*i;
  addChild(bola); 
}

Podemos escribir, en algún momento

Código ActionScript :

var mc:Bola=getChildByName("bola3") as Bola
//ahora usamos mc, para referirnos a "bola3"
mc.y=20

Hay varias cosas interesantes en ese código
1.-Observa que hemos usado una variable que hace referencia a "bola3"
2.-Observa que hacemos una "conversión de cast" a lo que nos devuelve el método getChildByName -ese "as Bola" del final-

Vale, he dicho que ya no se usa el nombre de instancia, sino variables que hacen referencia a los MCs. En tu código, en el bucle has puesto

Código ActionScript :

for (var i=1;i<6;i++){ 
  var bola:Bola=new Bola(); 
  bola.name="bola+i"; 
  bola.x=80*i;
  addChild(bola); 
}
trace(bola)  //<--saldrá null(*)

Al declarar la variable DENTRO del bucle, hemos usado una variable que ya no tendrá valor fuera del bucle, esto es, una variable temporal. Podríamos haber usado una variable fuera del bucle

Código ActionScript :

var bola:Bola;  //<--la declaramos aquí
for (var i=1;i<6;i++){ 
  bola=new Bola(); 
  bola.name="bola+i"; 
  bola.x=80*i;
  addChild(bola); 
}
trace (bola) //tendrá el valor de la última "bola" creada

Si queremos tener todas las "bolas" controladas, podemos usar un array

Código ActionScript :

var bolaArray:Array=new Array();  //<--Declaramos aquí el array
for (var i=0;i<6;i++){  //<--te he cambiado el índice porque los arrays comienzan con 0 
  bolaArray.push(new Bola());
  bolaArray[i].name="bola+i"; 
  bolaArray[i].x=80*i;
  addChild(bolaArray[i]); 
}
//y podríamos escribir
bolaArray[2].y=300
}


Resumiendo
1.-NO tiene nada que ver el "nombre de instancia" con la propiedad "name" de un MC
2.-La propiedad name sólo sirve para poder usar un getChildByName
3.-A los MCs se los controla mediante "variables" que hacen referencia al MC

El 4º punto es importante. Cuando damos nombre de instancia a un MC en tiempo de diseño -cuando lo tenemos en el escenario-, Flash traduce automáticamente ese nombre de instancia por una VARIABLE si en las opciones del compilador le hemos indicado que "declare como variables las instancias del escenario" (que es la opción por defecto)

Por Eliseo2

710 de clabLevel



 

msie8
Citar            
MensajeEscrito el 27 Sep 2009 10:21 pm
Uf! Muchas gracias por esa explicación. Te digo, yo sé que en AS3 las cosas han cambiado porque yo aprendí a trabajar un poco con el dos, pero me pasé al 3 y ahora solo manejo éste. El 2 casi lo tengo olvidado, me cuesta traducir del uno al otro :D Pero siempre veo como a todos se les facilia usar el duplicateMovieCLip, y me pergunto por qué no existe algo similar en el 3.

Siempre que instancio un elemento en AS3, tego que declarar la variable y todo esto. El proceso no es difícil, para nada, desde que uno empieze por entender addChild y similares. Pero lo que nunca he logrado hacer es un loop que instancie los elementos y me permita controlarlos. No soy el más experto, pero he buscado mucho sin encontrar la respuesta. Y si necesitas 500 elementos iguales, pues esto se vuelve interminable. Por eso la razón del post.

Entonces, me parece muy buena explicación esa. En este momento no tengo a mano mi pc con lo necesario (estoy en uno prestado), pero esta noche apenas lo tenga a mano voy a hacer el intento con el Array y declarando la variable por fuera del loop. Allí estaríamos haciando 7 por lo que empezamos con array desde 0. pero hay un error en el código que yo dejé en un principio, por haberlo posteado mal, en el ejemplo que usé está bien: en vez de

Código ActionScript :

 bola.name="bola+i";

debe ser:

Código ActionScript :

 bola.name="bola"+i;


Este error, por lo tanto quedó en todos los códigos y lo aclaro por si alguien accede a este post buscando información

Pero hay algo que no entiendo. Si me dices que una variable que está dentro de un loop es temporal, no entiendo lo siguiente. El valor final de la bola es bola 6. Si yo le digo

Código ActionScript :

bola6.y+=30:
si me la reconoce. PEro las demás no. Es algo que no acabo de entender.

En todo caso según la lógica que explicas y el código que das, parece que esto funciona, y espero que así sea. Apenas lo pruebe respondo de nuevo.


MIL GRACIAS>
Eskombro

Por eskombro

9 de clabLevel



 

msie8
Citar            
MensajeEscrito el 28 Sep 2009 06:18 am
Que desapareciera "duplicate" tiene que ver con que también ha desaparecido attachMovie. Ahora todos los MCs provienen de una Clase -podemos irnos al símbolo y darle un nombre de Clase -así como un nombre de Clase Base (que suele ser MovieClip)-. Esto hace que la "traducción" del "attachMovie" quede simplemente como

Código ActionScript :

var mc:Clase1=new Clase1()
addChild(mc)

Claro, ya no existe duplicate. Cada vez que queramos crear un "objeto" de una Clase, lo haremos con el código anterior (creamos un nuevo objeto con new y lo añadimos a la "displayList" con addChild)
NOTA: En esta página tienes la "migración" de AS2 a AS3

Por Eliseo2

710 de clabLevel



 

firefox
Citar            
MensajeEscrito el 29 Sep 2009 04:24 am
El código funciona a la perfección, solo que el ultimo cierre de llaves sobra. Excelente explicación, mil gracias!!!!!!!!!!!!!!!! Espero le sirva igual a mucho otros.

Un saludo
Eskombro

Por eskombro

9 de clabLevel



 

chrome
Citar            
MensajeEscrito el 29 Sep 2009 05:44 am
Tengo una gran duda! Utilicé el código y me funcionó a la perfección. Pude hacer que se reprodujera el clip automáticamente pudiendo controlar cada una de las 'bolas' creadas. Excelente. Pero tengo una gran duda:

Probé a hacer un juego con esto para intentar comprender el código a fondo. Creé una clase externa en donde se crearan toda las bolas. En el juego, voy añadiendo una bola a medida que sucede un evento. Pero,

¿Por que no puedo usar el hitTestObject con esas bolas creadas en general, sino una por una?

Es decir, como las bolas son movieclips, pues claro que puedo hacer el hitTestObject. Pero para programar el código me toca hacer un hitTestObject para cada movieclip de la Bola: bolaArray[0], bolaArray[1]... hasta el Fin. No puedo hacer el hitTestObject con los elementos de la clase Bola() como tal, porque me toca decirle que haga el hitTest con bolaArray, y esto es una variable Array a la cual no le puedo dar esta función.

Como podría hacer esto?

Muchas gracias.
Eskombro

Por eskombro

9 de clabLevel



 

chrome
Citar            
MensajeEscrito el 29 Sep 2009 06:28 am
Eskombro, efectivamente el método hitTestObject lo que hace es comprobar el "HIT" de los objetos -concretamente con objetos que sean DisplayObject -o que extiendan de una clase-.
Existen diversas soluciones con los hitTest (pongo las que recuerdo)
1.-El evidente que es hacer el hitTestObject con todos los objetos. Podemos recorrernos el bucle con un for normal o usar el método "map" de un Array
2.-Meter todos los "objetos" en un MC "contenedor" y usar un hitTestPoint sobre cuatro o más puntos del MC que queremos comprobar que "choca" con alguno de los otros -los cuatro o más puntos serían las esquinas del rectángulo que abarca a nuestro MC- Es bastante efectivo siempre que nuestro MC con el que queramos comprobar los choques sea más o menos "rectangular"
3.-Usar algo parecido a lo que usó Grant Skinner

NOTA:Si queremos comprobar los choques entre las "bolas" no hay más remedio que comprobar el choque de cada una con las siguientes en el array

Por Eliseo2

710 de clabLevel



 

firefox
Citar            
MensajeEscrito el 29 Sep 2009 06:31 am
Pero me refiero a que tengo un 'cursor', digamos un cuadro... Y quiero comprobar el hitTest de ese cuadro con cada una de las bolas... No puede ser un contenedor, porque no comprobaría el choque con cada bola, sino con todo el contenedor...

Como es lo de los mapas de array?

Voy a mirar el link. Mil gracias eliseo, estoy aprendiendo bastante de esto...

Un saludo.

Por eskombro

9 de clabLevel



 

chrome
Citar            
MensajeEscrito el 29 Sep 2009 07:20 am

eskombro escribió:

Pero me refiero a que tengo un 'cursor', digamos un cuadro... Y quiero comprobar el hitTest de ese cuadro con cada una de las bolas... No puede ser un contenedor, porque no comprobaría el choque con cada bola, sino con todo el contenedor...

Es un hitTestPoint (el tercer argumento ha de ser "true").
Si tu "cursor" se llama "cursor", comprobamos los cuatro puntos (cursor.x, cursor.y), (cursor.x+cursor.width,cursor.y), (cursor.x,cursor.y+cursor.height) y (cursor.x+cursor.width,cursor.x+cursor.height). Si algún punto ha hecho un hitTestPoint es porque el "cursor" ha chocado.
Realmente lo de los cuatro puntos es una "aproximación grosera". Podemos imaginar nuestro MC con varios "puntos" en su perímetro, lo que comprobamos son puntos de ese perímetro ¿cuántos? Pues depende de la precisión que queramos, de cómo sea ese perímetro y de lo grande que sea nuestro MC. Por ejemplo si nuestro "cursor" es un triángulo podríamos comprobar sólo los vértices del triángulo ¿sacrificamos la precisión o la velocidad? Pues es una pregunta como si queremos más a papá o a mamá. Debemos tomar una solución de compromiso. Cuantos más puntos más comprobaciones tendremos que hacer y por tanto será más lento.

Por Eliseo2

710 de clabLevel



 

firefox

 

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