POO - Rocco

Anuncio
Guía práctica
Desarrollo de un juego de comparaciones
con AS3 y paquetes
Preparado por Fco. Rocco
CREANDO UN JUEGO DE COINCIDENCIAS: arrastrar y soltar
Empezaremos con 8 elementos que forman nuestro
juego: 4 textos y 4 dibujos.Crearemos una clase para los 4 textos del escenario,
y la llamaremos txtBanderas.as. Recordemos que al escribirla con mayúscula
nos referimos a una clase.
POO:
Arrastrar y soltar
Comenzamos entonces escribiendo el siguiente código dentro de ella:
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
package
{
import.flash.display.movieClip;
import.flash.events.MouseEvent;
public class txtBandera extends MovieClip
{
public function txtBandera ( ): void
{
this.addeventListener( MouseEvent.MOUSE_DOWN, arrastrarlo);
this.addeventListener( MouseEvent.MOUSE_UP, soltarlo);
}
private function arrastrarlo (e: MousEvent) : void5
{
this.startDrag ( );
private function soltarlo(e: MousEvent ) : void7
{
this.stopDrag ( );
}
}
Cometarios:
01: Lo 1ro es crear un paquete que contenga una clase publica la que
llamaremos “txtBandera”
03-04: Importamos las clases que ocuparemos
06: Creamos propiedades para las clases, las que son variables
públicas.Incluimos todos los métodos y propiedades de la clase MovieClip
con la palabra clave de definición extends.
08: Agregamos los detectores de eventos dentro de una función constructora
Arrastrar y soltar
POO:
para que las funcionalidades de arrastrar y soltar ocurran, es decir al hacer
clck en el mouse y al soltarlo. Para ello creamos una función pública que
aloje estos detectores.
10: A esta clase (this) le agregamos un detector de eventos del tipo
MouseEvent..MOUSE_DOWN, para que la función ocurra solamente cuando
mantenemos el botón del mouse presionado. La función CLICK es cuando
hacemos click y luego soltamos el botón. Sin embargo no es lo que queremos.
11: A esta clase (this) le agregamos un detector de eventos del tipo
MouseEvent..UP_DOWN, para que la función cuando soltemos el botón del
mouse que se ha presionado.
13: Definimos la funcionalidad de arrastrar que se activará en los textos del
escenario, con la función privada “soltar”. Es privada porque los demás objetos
no necesitan saber que es lo que pasa al arrastra y soltar. Declaramos la
variable “e” la que almacena los datos que envía el detector de eventos.
15: Para arrastrar un objeto en el escenario ocupamos la funcion startDrag
17: Definimos la funcionalidad de soltar que se activará en los textos del
escenario, con otra función privada llamada “soltar”. Declaramos la variable
“e” la que almacena los datos que envía el detector de eventos.
19: Para soltar un objeto en el escenario ocupamos la función stopDrag.
Ahora que hemos escrito el código base para nuestro juego de comparación,
asociamos el archivo .fla con el archivo .as. Sin embargo debemos tener
presente que ActionScript nos pedirá un nombre único de clase al asociar
cada movieclip en el escenario. Si no hacemos esto nos arrojará un error.
De modo que la manera correcta de vincular ambos archivos es:
CREANDO UN JUEGO DE COINCIDENCIAS: detectando colisiones
POO:
Colisiones
Lo que debemos tener en mente es el target u objetivo que debemos darle a
cada texto, de manera que este coincida con su bandera correspondiente .
Para esto necesitamos una variable pública para la clase txtBandera y así darle
ciertas propiedades. Creamos el archivo txtBandera.as con el siguiente código:
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
package
{
import.flash.display.MovieClip;
import.flash.events.MouseEvent;
public class txtBandera extends MovieClip
{
public var _acertar:MovieClip;
public function txtBandera ( ): void
{
this.addeventListener( MouseEvent.MOUSE_DOWN, arrastrarlo);
this.addeventListener( MouseEvent.MOUSE_UP, soltarlo);
}
private function arrastrarlo (e: MousEvent) : void
{
this.startDrag ( );
private function soltarlo(e: MousEvent ) : void
{
this.stopDrag ( );
}
}
Cometarios:
08: Declaramos una variable de nombre _acertar la que almacenará el objetivo
actual al que estamos apuntando. Es una convención general que al crear
una variable pública que le de propiedades a una clase, ésta comience
con guión bajo. Definimos el tipo de variable que será MovieClip, por estar
dirigida a alguna de las banderas.
En este punto creamos un 2do archivo .as que servirá como una clase
documento para nuestro juego y lo llamaremos “Puntaje.as”. De manera que
linkeamos nuestro archivo .fla con la clase que recién crearemos:
POO:
Colisiones
El código para la nueva clase documento Puntaje es:
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
package
{
import flash.display.MovieClip;
import flash.events.MouseEvent;
public class Puntaje extends MovieClip
public function Puntaje():void
{
// acertar es la propiedad y Chile_mc el objetivo de txtChile_mc
txtChile_mc._acertar = Chile_mc;
txtEcuador_mc._acertar = Ecuador_mc;
txtEmiratos_mc._acertar = Emiratos_mc;
txtIndia_mc._acertar = India_mc;
txtChile_mc.addEventListener(MouseEvent.MOUSE_UP, resultado);
txtEcuador_mc.addEventListener(MouseEvent.MOUSE_UP, resultado);
txtEmiratos_mc.addEventListener(MouseEvent.MOUSE_UP, resultado);
txtIndia_mc.addEventListener(MouseEvent.MOUSE_UP, resultado);
}
private function resultado(e:MouseEvent):void
{
// mc1_mc.hitTestObject (mc2_mc) // Fórmula a ocupar:
if (e.currentTarget.hitTestObject(e.currentTarget._acertar))
trace (” Aquí está el resultado...”);
}
}
}
POO:
Colisiones
Comentarios:
01: Comenzamos creando un paquete de clases
03-04: Importamos las clases que ocuparemos
06: Creamos clase pública Puntaje ( mismo nombre que el archivo .as) que
usará la clase MovieClip, debido a que la línea de tiempo principal es
básicamente un gran Movie Clip.
08: Dentro de la clase pública Puntaje creamos la función pública constructora
con el mismo nombre. Esta función constructora almacena todos los datos
necesarios para que el juego sea funcional.
11 al 14: Creamos un grupo de propiedades del tipo _acertar para cada
bandera. Recordemos que en el archivo txtBandera.as, ya habíamos creado
la variable _acertar, la que ahora será usada para cada bandera.
16 al 19: A los textos, le agregamos detectores de eventos del tipo
MouseEvent.MOUSE_UP y definimos el nombre de la función “resultado” que
recibirá los datos enviados por ellos.
22: Creamos la función privada “resultado” y declaramos la variable “e” que
almacena los datos del tipo MouseEvent enviados por el detector. Cerramos
con void para que no retorne valores
25:La función a ejecutarse corresponde a la formula mc1_mc.hitTestObject
(mc2_mc) la que retornará valores true o false. Si mc1_mc toca a
mc2_mc, el método retorna true; si no es así retorna false .Esta fórmula
la colocaremos dentro de una declaración if, de modo que si el movieclip1
toca al movieclip2, algo debe pasar.
De manera que en lugar de mc1_mc colocamos el actual Movie Clip que
gatilla al detector de eventos ( txtChile_mc, etc), y la manera de hacerlo es
usando la propiedad currentTarget.
Reemplazamos los elementos correspondientes y tenemos:
currentTarget.hitTestObject (e. currentTarget._acertar)
en donde:
currentTarget corresponde a txtChile_mc que es el Movie Clip que se
arrastrará y soltará.
Propiedad hitTestObject prueba si un objeto a colisionado con otro.
Cuando este Movie Clip esté tocando a Chile_mc (e. currentTarget._acertar),
el detector se activará.
26: Si el retorno es true, ejecute el trace ” Aquí está el resultado...”
POO:
Respuestas a colisiones
CREANDO UN JUEGO DE COINCIDENCIAS: respondiendo a las colisiones.
Lo que pretendemos en este capítulo, es hacer mas ineractivo nuestro juego,
por lo que estudiaremos como aplicar la desaparición de un objeto cuando
colisione con otro. Para esto en la declaración if de nuestro arhivo Puntaje.as.
Para lograr lo pretendido reemplazamos la función trace por el método
removeChild, y que su función es eliminar ciertos objetos definidos por nosotros
en nuestro ejercicio, queremos que desaparezcan txtChile_mc y Chile_mc por
lo que nuestro código sería:
01
02
03
04
05
if (e.currentTarget.hitTestObject(e.currentTarget._acertar))
{
removeChild (e.currentTarget);
removeChild (e.currentTarget._acertar);
}
Este pareciera el código correcto, sin embargo al correr la película,
nos encontramos con el siguiente error:
1118: Conversión implícita de un valor con tipo estático Object a un tipo
flash.display:DisplayObject posiblemente no relacionado.
El objeto removeChild es el DisplayObject y e.currentTarget es la instancia
de la clase Object .La razón del error es que flash está esperando cierto tipo
de objeto pero obtiene otro, por lo que debemos definir más claramente el
tipo de objeto que deseamos eliminar. Lo que haremos será convertir la
instancia en un Movie Clip:
01
02
03
04
05
if (e.currentTarget.hitTestObject(e.currentTarget._hitTarget))
{
removeChild (MovieClip (e.currentTarget));
removeChild (e.currentTarget._hitTarget);
Ahora si probamos la película veremos que corre OK.
Con un pequeño cambio en el tipo de easing usado, con el fin de mover el
fondo, cada vez que pinchemos en el escenario:
Pantalla de felicitaciones
POO:
01
02
03
04
05
06
07
08
09
10
import fl.transitions.Tween;
import fl.transitions.easing.*;
stage.addEventListener(MouseEvent.MOUSE_DOWN,animacion); //
stage puede reemplazarse por Chile_mc
function animacion(e:MouseEvent):void
{
new Tween (mapa_mc, "x", Regular.easeOut, stage.x,mouseX,1,true);
new Tween (mapa_mc, "y", Regular.easeOut, stage.y,mouseY,1,true);
}
CREANDO UN JUEGO DE COINCIDENCIAS: pantalla de felicitaciones.
En este capítulo, crearemos una pantalla que aparezca cada vez que hemos
completado las 4 banderas, para felicitarnos por completar el juego. Lo primero
será crear un 3er layer en nuestro archivo 04_Banderas.fla en el cual dibujamos
un rectángulo y enseguida con F8 lo convertimos en movieclip. Al hacerlo nos
aseguramos de configurar su exportación para ActionScript:
Echo esto, con Crtl + E , entramos al movieclip recién creado
y comenzamos su edición, para que finalmente luzca asi:
Pantalla de felicitaciones
POO:
Despés de esto, volvemos a nuestro escenario principal y borramos el layer
recién creado que contiene la pantalla de felicitaciones, de modo que solo
dispongamos de ella a través del movieclip guardado en biblioteca. Vamos
ahora a nuestro archivo Puntaje.as al que agregaremos las siguientes lineas
de código:
Pantalla de felicitaciones
POO:
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
POO:
Pantalla de felicitaciones
Comentarios:
09: Declaramos la variable pública “miPuntaje” de tipo numérica y la seteamos
por defecto en su valor mínimo 0.
30: Incrementamos el valor de “miPuntaje” en 1 cada vez que los removeChild
de arriba se ejecuten.
31: Hacemos la comparación de elementos eliminados en el escenario, y
cuando sea igual a 4 se ejecuta la función dentro de los paréntesis { }
32: Declaramos la variable “ganador” del tipo “Ganar”
33-34: Centramos el Movie Clip en el escenario.
35: Atachamos el Movie Clip de felicitaciones (el que resolvimos al comienzo)
al escenario.
Al probar la película vemos que al finalizar el juego, se abre la pantalla de
felicitaciones. OK.
De no haber coincidencia haremos que los textos vuelvan a su posición
original. Para esto , en la función privada “resultado” de nuestro clase
Puntaje.as, debemos agregar una declaración else
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
private function resultado(e:MouseEvent):void
{
if (e.currentTarget.hitTestObject(e.currentTarget._acertar))
{
removeChild (e.currentTarget._acertar);
miPuntaje++;
var ganador:Ganar = new Ganar();
ganador.x = stage.stageWidth /2;
= stage.stageHeight /2;
addChild (ganador);
}
else
{
// función a ejecutar: que los textos regresen a su posición
de origen si no coinciden con la bandera correspondiente.
}
Comentarios:
POO:
Pantalla de felicitaciones
12: Si if retorna false, entonces ejecute la función dentro de else. Sin embargo,
debemos tener a mano un par de variables que ayuden a ejecutar esta
sentencia else, por lo que debemos ir a la clase txtBandera.as y declararlas:
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
package
{
import.flash.display.MovieClip;
import.flash.events.MouseEvent;
public class txtBandera extends MovieClip
{
public var _acertar:MovieClip;
// Declaramos las variables públicas inicioX e inicioY las que
serán usadas por la clase Puntaje.as
public var _inicioX:Number; // y que almacenan los valores iniciales
de las coordenadas x,y
public var _inicioY:Number;
public function txtBandera ( ): void
{
this.addeventListener( MouseEvent.MOUSE_DOWN, arrastrarlo);
this.addeventListener( MouseEvent.MOUSE_UP, soltarlo);
}
private function arrastrarlo (e: MousEvent) : void
{
this.startDrag ( );
private function soltarlo(e: MousEvent ) : void
{
this.stopDrag ( );
}
}
Otro aspecto a considerar es que estas variables recién declaradas, también
se necesitan en la función pública Puntaje.
El código luce asi:
Pantalla de felicitaciones
POO:
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
package
{
import flash.display.MovieClip;
import flash.events.MouseEvent;
import Ganar;
public class Puntaje extends MovieClip
private var miPuntaje = 0;
public function Puntaje():void
{
txtChile_mc._inicioX = txtChile_mc.x;
txtChile_mc._inicioY = txtChile_mc.y;
txtEcuador_mc._acertar = Ecuador_mc;
txtEcuador_mc._inicioX = txtEcuador_mc.x;
txtEcuador_mc._inicioY = txtEcuador_mc.y;
txtEmiratos_mc._acertar = Emiratos_mc;
txtEmiratos_mc._inicioX = txtEmiratos_mc.x;
txtEmiratos_mc._inicioY = txtEmiratos_mc.y;
txtIndia_mc._acertar = India_mc;
txtIndia_mc._inicioX = txtIndia_mc.x;
txtIndia_mc._inicioY = txtIndia_mc.y;
txtChile_mc.addEventListener(MouseEvent.MOUSE_UP, resultado);
txtEcuador_mc.addEventListener(MouseEvent.MOUSE_UP, resultado);
txtEmiratos_mc.addEventListener(MouseEvent.MOUSE_UP, resultado);
txtIndia_mc.addEventListener(MouseEvent.MOUSE_UP, resultado);
}
private function resultado(e:MouseEvent):void
{
if (e.currentTarget.hitTestObject(e.currentTarget._acertar))
{
removeChild (e.currentTarget._acertar);
miPuntaje++;
if (miPuntaje == 4)
{
var ganador:Ganar = new Ganar();
ganador.x = stage.stageWidth/2;
ganador.y = stage.stageHeight/2;
addChild(ganador);
}
}
44
45
46
47
48
49
50
51
else
{
e.currentTarget.x = e.currentTarget._inicioX;
e.currentTarget.y = e.currentTarget._inicioY;
}
}
}
}
POO:
Aregando sonido
Comentarios:
Cuando el archivo se carga por 1ra vez, lo hace con los valores almacenados
en las variables numéricas declaradas en la clase txtBandera.as (_inicioX,
_inicioY). Por eso, si las coordenadas (x, y) del texto al comenzar la carga
fueran (5, 8), estos serán los valores a los que volverá si no hay coincidencia
con las banderas. De modo que:
19-20: Al correr el programa, los valores almacenados en las propiedades
inicioX e inicioY de txtChile_mc (etc) se igualan (o cargan) con el valor
registrado en las coordenadas x e y actual.
46-47: Si if retorna false se hace uso de este valor almacenado, y el texto
vuelve a sus coordenadas originales.
CREANDO UN JUEGO DE COINCIDENCIAS: agregando sonido.
Finalmente agreguemos un sonido externo, el cual debe estar en la misma
carpeta que el resto de los archivos:
01
02
03
04
05
06
07
08
09
10
11
package
{
import
import
import
import
import
flash.display.MovieClip;
flash.events.MouseEvent;
Ganar;
flash.media.Sound;
flash.net.URLRequest;
public class Puntaje extends MovieClip
private var miPuntaje = 0;
Aregando sonido
POO:
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
private var miSonido:Sound;
public function Puntaje():void
{
txtChile_mc._inicioX = txtChile_mc.x;
txtChile_mc._inicioY = txtChile_mc.y;
txtEcuador_mc._acertar = Ecuador_mc;
txtEcuador_mc._inicioX = txtEcuador_mc.x;
txtEcuador_mc._inicioY = txtEcuador_mc.y;
txtEmiratos_mc._acertar = Emiratos_mc;
txtEmiratos_mc._inicioX = txtEmiratos_mc.x;
txtEmiratos_mc._inicioY = txtEmiratos_mc.y;
txtIndia_mc._acertar = India_mc;
txtIndia_mc._inicioX = txtIndia_mc.x;
txtIndia_mc._inicioY = txtIndia_mc.y;
txtChile_mc.addEventListener(MouseEvent.MOUSE_UP, resultado);
txtEcuador_mc.addEventListener(MouseEvent.MOUSE_UP, resultado);
txtEmiratos_mc.addEventListener(MouseEvent.MOUSE_UP, resultado);
txtIndia_mc.addEventListener(MouseEvent.MOUSE_UP, resultado);
var solicitarSonido:URLRequest = new URLRequest (”blip.mp3”);
miSonido = new Sound ( );
miSonido.load (solicitarSonido);
private function resultado(e:MouseEvent):void
{
if (e.currentTarget.hitTestObject(e.currentTarget._acertar))
{
removeChild (e.currentTarget._acertar);
miPuntaje++;
miSonido.play ( );
if (miPuntaje == 4)
{
var ganador:Ganar = new Ganar();
ganador.x = stage.stageWidth/2;
ganador.y = stage.stageHeight/2;
addChild(ganador);
}
}
else
{
e.currentTarget.x = e.currentTarget._inicioX;
e.currentTarget.y = e.currentTarget._inicioY;
}
54
55
56
57
58
}
}
}
POO:
Agregando sonido
Comentarios:
07-08: Ubicaciones de carpetas donde se encuentarn las clases que
ocuparemos.
31: Para que el sonido se manifieste, declaramos la variable “solicitarSonido”
y almacenamos un objeto de sonido dentro de ella.
Dentro de la función constructora, que es la que ejecuta las acciones, creamos
el objeto de sonido:
Para ocupar un archivo externo, debemos crear una instancia para la clase
URLRequest. Esta clase es usada cada vez que debamos acceder a una URL
externa o archivo externo La manera de hacerlo es declarando la variable
“solicitarSonido” del tipo URLRequest y creamos una nueva instancia u objeto
la que va dentro de los paréntesis.
32: Creamos el objeto de sonido propiamente tal. En la línea 11 ya hemos
almacenado el sonido en la variable “miSonido”; ahora la seteamos para crear
una nueva instancia u objeto de sonido.
33: En la variable recién seteada, ocupamos el método load, y dentro de los
paréntesis, invocamos el objeto solicitado.
40: Después de haber incrementado el valor del puntaje en 1, ubicamos la
reproducción del sonido.
Guía práctica
Desarrollo de un juego de comparaciones
con AS3 y paquetes
Preparado por Fco. Rocco
Descargar