Videojuegos - Técnicas Básicas

En este capítulo vamos a usar todo lo que hemos aprendido hasta ahora para hacer nuestro primer videojuego.

 Cazando mosquitos - Introducción

Ya hemos aprendido a usar variables y procedimientos, a mostrar imágenes en la pantalla, a usar eventos, bloques de control, sensores y muchas cosas más. Ahora vamos a usar todo esto para hacer un pequeño videojuego que consiste en cazar con el dedo un mosquito que se mueve aleatoriamente por la pantalla.
Ya sabes también dónde encontrar los bloques que vamos a necesitar y cómo usarlos de forma correcta. A partir de ahora vamos a seguir los pasos necesarios para hacer este videojuego pero sin entrar en tanto detalle como hasta ahora. Si necesitas recordar cómo hacer algo puedes volver atrás para ver cómo lo hicimos antes. Puedes modificar la apariencia, el tamaño del texto y demás cosas como más te guste. También te recomendamos que uses los mismos nombres de componentes que te vamos a sugerir para que no te pierdas. Cuando usemos algún bloque que no hayamos visto antes te explicaremos cómo hacerlo. Al final de este reto encontrarás el programa completo para que puedas ver cómo lo hemos hecho nosotros. Las imágenes y sonidos que vamos a usar los puedes encontrar en la carpeta de materiales.

 El interfaz de usuario

Comienza un proyecto nuevo desde el Diseñador y llámalo: "cazando_mosquitos".
Nuestra pantalla va a tener dos áreas claramente diferenciadas. En primer lugar, en la parte superior de la pantalla vamos a tener la puntuación del juego y debajo un canvas donde se moverá el mosquito.
Vamos con la puntuación: Necesitamos un componente HorizontalScreenArrangement que ocupe todo el ancho de pantalla (Width=FillParent) y dentro pondremos dos etiquetas.
Una se llamará etiqueta_puntuacion y la otra etiqueta_intentos. Juega con las propiedades para colocarlos como más te guste. El texto de las etiquetas lo pondremos desde el Editor de bloques.
Ahora añade debajo un componente canvas al que le vamos a cambiar el fondo por la imagen imagen_mosquito_fondo.
Dentro de este canvas vamos a colocar dos imágenes (ImageSprite). A la primera llámala imagen_mosquito y usa la imagen de la librería llamada imagen_mosquito.
A la segunda llámala imagen_mosquito_muerto y usa la imagen llamada imagen_mosquito_muerto.png.
De momento queremos que esta imagen no sea visible así que cambia la propiedad Visible para ocultarla.
Vamos con los sonidos: Añade tres componentes Sound. Y llámalos respectivamente sonido_mosquito_muerto, sonido_mosquito_fallo y sonido_mosquito_fin.
A cada uno de estos componentes añádeles los archivos de sonido correspondientes con el mismo nombre.
10 Añade también un componente Player y usa el archivo de sonido mosquito_volando.mp3.
Recuerda que el componente Sound nos permite usar pequeños sonidos en nuestras aplicaciones mientras que el componente Player se usa para archivos de sonido de mayor duración. En nuestro caso lo vamos a usar para el sonido que hace el mosquito mientras se mueve por la pantalla.
11 Añade también un componente Notifier que vamos a usar para mostrar una ventana con la puntuación final.
12 Por último vamos a añadir dos componente Reloj (clock).
13 Llama al primero reloj_mover_mosquito y pon el intervalo a 1000 (1 segundo). Este reloj lo vamos a usar para mover el mosquito por la pantalla cada segundo.
14 Al segundo reloj lo llamaremos reloj_final_partida y lo vamos a usar para controlar el tiempo de juego.
15 Cambia el intervalo a 60000 (1 minuto). Cuando se cumpla el minuto la partida terminará y nos mostrará la ventana con la puntuación final.
Ahora que tenemos el interface de usuario resuelto vamos a pensar un poco cómo vamos a plantear la programación de nuestro videojuego.
16 En primer lugar queremos que nuestro mosquito se mueva por la pantalla apareciendo y desapareciendo cada vez en un sitio distinto de forma aleatoria. Para controlar cada cuanto tiempo se mueve nuestro mosquito hemos creado el reloj reloj_mover_mosquito. En segundo lugar queremos que la partida termine pasado un minuto de tiempo y para eso hemos creado el reloj reloj_final_partida. Para ambos relojes tendremos que crear el evento .Timer correspondiente donde usaremos los bloques necesarios.

 Moviendo el mosquito

17 Vamos a empezar por mover el mosquito. Para asegurarnos de que el reloj reloj_mover_mosquito está activo al arrancar nuestro programa, vamos a activarlo nada más arrancar. Coge el evento screen.Initialize y dentro activa el reloj: (reloj_mover_mosquito.TimerEnable = True).
18 Aprovecha también para que empiece el sonido del mosquito volando. (call sonido_mosquito_volando.Start)
19 Ahora vamos a por el evento del reloj que se activará cuando se cumpla el intervalo. "when reloj_mover_mosquito.Timer" y dentro vamos a mover el mosquito usando "imagen_mosquito.MoveTo".
La coordenada X será un número aleatorio entre 1 y el ancho del canvas (canvas.Width) y la coordenada Y será otro número aleatorio entre 1 y el largo de canvas (canvas.Height). Con esto nuestro mosquito debería de moverse ya.

 Cazando el mosquito

20 Si tocamos con el dedo un sprite se activa el evento .TouchDown. Vamos a usar este evento para saber si el usuario ha tocado el mosquito mientras este se mueve por la pantalla. El evento que necesitamos se llama imagen_mosquito.TouchDown. Cógelo.
21 Lo primero que tenemos que hacer cuando se activa este evento es parar el reloj que mueve al mosquito, de lo contrario se seguirá moviendo por la pantalla. Para parar el reloj usaremos el bloque (reloj_mover_mosquito.TimerEnable=false)
22 El siguiente paso es ocultar la imagen del mosquito porque queremos mostrar otra imagen distinta donde aparecerá el mosquito muerto que nos indicará que le hemos cazado. (set imagen_mosquito.Visible=false).
23 Ahora vamos a mover la imagen del mosquito muerto (que está de momento oculta) a la posición donde estaba el mosquito cuando lo hemos cazado con el dedo (call imagen_mosquito_muerto.MoveTo). Las coordenadas donde estaba el mosquito están en las propiedades imagen_mosquito.X e imagen_mosquito.Y.
24 Una vez que la imagen del mosquito muerto está en posición vamos a hacerla visible (set imagen_mosquito_muerto.Visible=true)
Ahora si cazamos al mosquito aparecerá la nueva imagen en la misma posición. Vamos a añadir el sonido y alguna cosa más.
25 El sonido que vamos a usar cuando cazamos al mosquito está en el componente sonido_mosquito_muerto. Así que usa el bloque call sonido_mosquito_muerto.Play.
26 Vamos con el marcador. Para llevar la puntuación de nuestro videojuego vamos a usar dos variables. A la primera la vamos a llamar puntos y a la segunda intentos. Recuerda que se crean desde Built-in/Variables. Queremos que sean variables numéricas. Pon el valor 0 a ambas. Estos dos bloques que definen las variables las puedes poner al principio del programa para que queda más claro.
27 Como queremos que la puntuación aumente cada vez que cazamos un mosquito usaremos el bloque (set global puntos= global puntos + 1) ¿Recuerdas?
28 Ahora cambiamos la etiqueta para que muestre el resultado. Usa el bloque "set etiqueta_puntuación.Text" y pásale una cadena de texto formada por el texto "Mosquitos muertos: " + la variable (global puntos). Recuerda que se hace con el bloque text/ join.
29 Para que nuestro dispositivo vibre cuando cazamos un mosquito usa el bloque "call sonido_mosquito_volando.Vibrate y pásale el número 200.
30 Únicamente nos queda volver a activar el reloj que mueve el mosquito para que vuelva a volar y continuemos el juego. (set reloj_mover_mosquito.TimerEnable=true)
Si pruebas tu programa verás que el mosquito se mueve perfectamente y que cuando lo cazas, la imagen cambia y el mosquito se para. No vuelve a empezar. La razón es que hemos ocultado la imagen del mosquito al cazarlo pero no la hemos vuelto a hacer visible. Para conseguir el efecto que buscamos tenemos que ocultar la imagen del mosquito muerto y volver a mostrar la del mosquito vivo, pero tenemos que hacerlo nuevamente dentro del evento reloj_mover_mosquito.Timer. Haciéndolo de esta manera nos aseguramos de que siempre que el reloj se vuelva a poner a funcionar se borrará cualquier imagen del mosquito muerto anterior y se mostrará al mosquito vivo.
31 Dentro del evento reloj_mover_mosquito.Timer pero antes de moverlo (:moveTo) coloca los bloques "set imagen_mosquito_muerto.Visible=false" y "set imagen_mosquito.Visible=True". Verás como ahora funciona.

 Contando los intentos

32 Además de contar cuántos mosquitos cazamos, vamos a contar también los intentos que hacemos. Al igual que podemos saber cuándo hemos tocado un sprite usando el evento .TouchDown, podemos hacer lo mismo con el evento del canvas .TouchDown. Coge este bloque y mete dentro un bloque "call sonido_mosquito_volando.Vibrate=200" para que vibre el dispositivo.
33 Mete también dentro un bloque "call sonido_mosquito_fallo.Play" para que suene cuando fallamos.
34 Ahora vamos a por el marcador. Igual que hicimos con los puntos, ahora usa un bloque "set global intentos = global intentos +1.
35 Y por último usa un bloque "set etiqueta_intentos.Text y pon la cadena de texto "Intentos: " + la variable (global intentos) usando un bloque join.

 Fin de la partida

36 Recuerda que tenemos otro reloj funcionando que se llama reloj_final_partida que se activa cada minuto. Cuando este reloj cumpla el intervalo de un minuto que hemos fijado queremos que la partida termine, nos muestre un mensaje con el resultado y nos dé la opción de jugar otra vez o salir de juego. Coge el evento reloj_final_partida.Timer
37 Lo primero que tenemos que hacer es parar los dos relojes. El reloj_mover_mosquito lo tenemos que parar porque de lo contrario nuestro mosquito continuaría moviéndose aunque la partida hubiese terminado. El segundo reloj_final_partida lo tenemos que parar porque de lo contrario seguiría saltando aunque ya hubiésemos terminado la partida y cada vez que se activara aparecería una nueva ventana detrás de otra. Ya sabes cómo parar los relojes así que hazlo ahora dentro de este evento.
38 Ahora tenemos que parar el sonido del mosquito volando (.Stop) y después activar el sonido_mosquito_fin (.Play) que sonará al final de la partida.
39 Por último vamos a mostrar la ventana de final de partida usando el bloque "Notifier1.ShowChooseDialog. Como lo hemos añadido desde el Diseñador, lo encontrarás dentro de My Blocks.
40 Al parámetro message (mensaje) le pasamos una cadena de texto que junte el texto "Mosquitos muertos: " + (global puntos).
41 Al parámetro title (título) le pasamos el texto "Puntuación final".
42 Al parámetro button1Text el texto "Nueva partida".
43 Al parámetro button2Text el texto "Salir".
44 Y al último parámetro cancelable (cancelable) el valor lógico false.
Recuerda que usando el bloque Notifier.ShowChooseDialog mostramos una ventana en la pantalla de nuestra aplicación con los parámetros que hemos usado antes, ahora lo que tenemos que hacer es esperar la respuesta del usuario y decidir qué hacer en cada caso.
45 Al utilizar el bloque Notifier1.ShowChooseDialog en el paso anterior y cuando el usuario haya tomado una decisión se activará el evento Notifier1.AfterChoosing (después de elegir) así que busca este evento y ponlo en tu programa.
TRUCO
Cada vez tenemos más bloques en la pantalla y se empieza a hacer incómodo trabajar con el Editor de bloques. Si pulsas con el botón derecho del ratón en la pantalla aparecerá un menú que te permite ordenar los bloques en la pantalla (organize), expandirlos, etc. Ordena de vez en cuando los bloques usando este método para que te sea más sencillo trabajar. Recuerda también que tienes la posibilidad de hacer zoom para que te quepan más bloques en la pantalla aquí:

46 El evento Notifier1.AfterChoosing nos da un parámetro (choice) con la opción que ha elegido el usuario. Como los botones que hemos usado antes para esta ventana son "Salir" o "Nueva partida", este parámetro será uno de los dos. Por lo tanto únicamente tenemos que comprobar uno de ellos para saber cuál ha sido el que ha elegido. Coge un bloque de control ifelse y ponlo dentro del evento Notifier1.AfterChoosing.
Vamos a comprobar si el usuario quiere salir de la aplicación, de lo contrario, ya sabemos que quiere jugar otra vez.
47 Al parámetro test le vamos a pasar una expresión lógica (value choice = "Salir") Recuerda que el parámetro que nos pasa este evento lo tienes dentro de My Blocks/My definitions.
48 Si la respuesta es verdadera (el usuario quiere salir) coge un bloque "call close application" que encontrarás dentro de Built-in/Control. Este bloque termina la aplicación pero únicamente funcionará si instalas la aplicación directamente en tu dispositivo. Mientras estés conectado a través del Editor de bloques no es posible cerrar la aplicación.
49 Si la respuesta es negativa (el usuario quiere volver a jugar) lo primero que vamos a hacer es volver a poner los contadores a cero. "set global intentos = 0" y "set global puntos=0" y después cambia las etiquetas. Puedes duplicar los bloques que has usado antes "set etiqueta_intentos.Text" y "set etiqueta_puntuación.Text".
50 Ahora volvemos a activar los dos relojes "set reloj_mover_mosquito.TimerEnabled=true" y "set reloj_final_partida.TimerEnabled=true".
51 Finalmente volvemos a hacer sonar el sonido_mosquito_volando.Star.

 Últimos detalles

52 El sonido del mosquito volando tiene una duración de unos segundo y después se para. Para evitar esto y que siga sonando ininterrumpidamente vamos a usar un evento que se llama Sonido_mosquito_volando.Completed que se activa si la canción ha terminado.
53 Lo único que tenemos que hacer es poner dentro un bloque "call sonido_mosquito_volando.Start" para que empiece de nuevo automáticamente cada vez que se pare.

 El resultado final

Este es el programa que hemos hecho nosotros. Compáralo con el tuyo.

Recuerda que desde el diseñador hemos puesto el reloj_mover_mosquito a 1 segundo. Puedes cambiar este valor para hacer que el mosquito se mueva más rápido o más despacio.
También puedes cambiar el reloj_final_partida para hacer que las partidas duren más o menos.