Stratos => Tema de la semana => Mensaje iniciado por: mi-go en 09 de Diciembre de 2008, 01:20:31 am

Título: Subtema: Juegos Flash (2ªParte) Programación: Estructura, POO, Timers
Publicado por: mi-go en 09 de Diciembre de 2008, 01:20:31 am
Parte 1 => Programación: Introducción (http://www.stratos-ad.com/forums/index.php?topic=11681.0)
Parte 2 => Programación: Estructura, POO, Timers (http://www.stratos-ad.com/forums/index.php?topic=11682.0)
Parte 3 => Programación: Tweens, Sonido, Colisiones (http://www.stratos-ad.com/forums/index.php?topic=11691.0)
Parte 4 => Mercado: Métodos para ganar dinero (http://www.stratos-ad.com/forums/index.php?topic=11708.0)


1. Estructura del código AS3 para un videojuego

1.1. Una clase principal


En Tofu Hunter 1 todo el código del juego se encuentra en la capa “actions” del proyecto Flash.
Esto sería correcto sólo si el código de nuestra película Flash fuera algo muy sencillo, y en el caso de un videojuego no es así.
Es algo habitual encontrar esta forma de programar en flash en muchos de los ejemplos que hay en Internet, pero de esta forma el código se vuelve menos legible y menos reutilizable.



En Tofu Hunter 2 crearemos una clase principal del juego en un archivo “.as” externo a nuestro proyecto Flash, y un archivo .as por cada clase que creemos.
De esta forma el código queda separado de la parte de diseño de flash, y cualquier clase se podrá reutilizar en otro juego tan sólo copiando su archivo .as

Para crear la clase principal del juego y especificar al proyecto flash cual es:
1º- Creamos el archivo “.as”.

2º- Una vez abierto el nuevo documento AS lo guardaremos en la misma carpeta de nuestro proyecto Flash.

3º- En las propiedades de la película Flash en “Clase de documento” escribimos: “TofuHunter2”.

4º- En nuestra capa “actions” sólo introduciremos una llamada a nuestra función encargada de hacer iniciar el juego.




1.2. Programación organizada

En el código Tofu Hunter se mezclan las declaraciones de variables con las ejecuciones de instrucciones y las declaraciones de las funciones.

Parece que se ha programado con una visión lineal de un lenguaje estructurado, pero AS3 es un lenguaje orientado a objetos y esto nos posibilita tener una programación mucho más organizada y reutilizable.


En Tofu Hunter 2 tendremos nuestra clase principal del juego en la que declararemos nuestras variables globales (que son los atributos de nuestra clase principal) y que tendrá una función que se encargará de iniciar el juego y llamar al resto de funciones del juego, que podrán ser de la clase principal o de otras que creemos.

Por ejemplo, en vez de crear y programar el comportamiento de nuestro puntero en la línea principal del tiempo (como se hace en Tofu Hunter), haremos una clase “Puntero” de la que crearemos un instancia en nuestra clase principal del juego.
Dentro de la clase “Puntero” es donde programaremos el comportamiento de nuestro puntero, que será seguir el movimiento de la posición del ratón.
Finalmente en la clase principal tan sólo escribimos algo que queda mucho más claro:
var oPuntero:Puntero = new Puntero();
oPuntero.Inicio(this);


En Tofu Hunter 2 tendremos la siguientes clases:
-   TofuHunter2: la clase principal del juego.
-   Puntero: controla el comportamiento del puntero en el juego.
-   Tofu: todos los tofus serán objetos de esta clase.
-   EstrellaMalvada: estrella que nos servirá de ejemplo para las colisiones.
-   Utils: agrupa funciones genéricas que nos podrán servir en otros juegos.

Cada clase irá en un archivo .as distinto y todos deberán estar en la misma carpeta del proyecto Flash.





2. Tofus orientados a objetos

Como vimos en el apartado 1.2 Programación organizada, Tofu Hunter no utiliza el potencial de la programación orientada a objetos. Antes nos referíamos a la estructura del código en general, ahora veremos como se debería utilizar para la creación de instancias de una nueva clase Tofu.

En Tofu Hunter, en la clase principal del juego se crean nuevos Tofus de esta manera:
switch (randomTofu) {
         case 1:
            thisMC = new tofu1_mc();
            break;
         case 2:
            thisMC = new tofu2_mc();
            break;
         case 3:
            thisMC = new tofu3_mc();
            break;
         default:
            return;
            break;
      }
Y a continuación se cambian propiedades de thisMC y se le asignan ciertos Listeners. En total unas 70 líneas de código aproximadamente.


En Tofu Hunter 2 crearemos la clase Tofu, donde que será donde programaremos las propiedades con la que se tiene que iniciar un Tofu y los Listeners que le queramos asignar, ya sea en el propio constructor de la clase o en una función propia para iniciarlo.

Al iniciar el objeto de la clase Tofu también le añadiremos como hijo uno de los tres tipos posibles de MovieClips que son los dibujos de los Tofus.

En nuestra clase principal tan sólo escribiremos esto:
var oTofu:Tofu = new Tofu();
oTofu.IniciaTofu(this);



3. Timers para controlar el juego

En Tofu Hunter, una vez iniciado el juego, la mecánica básica se ejecuta cada vez que la película Flash dibuja una imagen de la animación (frame).
Incluyeron un Listener para el evento ENTER_FRAME:
stage.addEventListener(Event.ENTER_FRAME, enterFrameHandler);

La function enterFrameHandler es la que se encarga de generar los tofus que aparecen en pantalla.

Esto es algo peligroso porque estamos basando la velocidad de la mecánica del juego en la capacidad de mostrar imágenes del ordenador.
Si tenemos configurada la película Flash a 30 imágenes por segundo puede que en un ordenador antiguo, o en un juego Flash muy complejo, la cantidad de imágenes por segundo que el ordenador consiga mostrar sean 20. Con lo que la velocidad real del juego se está reduciendo también y realmente a 20 imágenes por segundo se podría haber seguido jugando con una suavidad visual de movimientos aceptable.


En Tofu Hunter 2 crearemos un Timer para controlar la creación de Tofus.
Un Timer que se ejecute cada 33 milisengundos es equivalente a llamar a una función en cada frame de una película configurada a 30 imágenes por segundo:
private var oTimerCreaTofu:Timer = new Timer(33);
oTimerCreaTofu.addEventListener("timer", TimerCreaTofuHandler);
oTimerCreaTofu.start();

De esta manera aunque en algún momento nuestro PC no fuera capaz de llegar a pintar 30 imágenes por segundo y viéramos las animaciones con menos de fluidez de imágenes, el desarrollo real del juego seguiría ejecutándose a la misma velocidad.

Cabe pensar aquí el caso en el que la lógica del juego fuera muy compleja y al no estar sincronizada con el pintado de las imágenes se mostrara una imagen con algún elemento en una situación no coherente con el resto de la escena, pero en la mayoría de los proyectos que realicemos que se de esta situación será algo más raro que el inconveniente explicado anteriormente por haber escrito la lógica en el evento Enter_Frame; y aún así siempre podremos crear un sistema para controlar esto.