Aprender Java creando un juego (Parte 5)


Hola y buen día para todos mis lectores, les tengo aquí la quinta parte del proyecto de la tortuga en el entorno Greenfoot, estamos muy cerca de concluirlo, así que ¡A programar! (obviamente antes de programar hay que leer lo que sigue)…
Cuando dejamos nuestro proyecto Java en la entrada previa, obtuvimos un pequeño y divertido juego en el cual una tortuga estaba comiendo pizza mientras trataba que las serpientes no se la comieran como se muestra en la siguiente imagen:



Si no has estado escribiendo los códigos de este proyecto hasta ahora, descarga e instala Greenfoot, y entonces visita las otras entradas de este blog (Parte 1, Parte 2, Parte 3, Parte 4) y únete en esta sesión.

Mejorando las serpientes
En nuestra versión actual, el movimiento de las serpientes está controlado por estas 2 líneas de código:
El efecto es que las serpientes siempre se mueven hacia adelante, y giran en un ángulo aleatorio (20 grados a la derecha o izquierda) a cada paso. Esto trabaja bastante bien cuando una serpiente está en medio de la pantalla. De todas formas, cuando esta golpea la orilla de nuestro mundo, queda atorada ahí por un rato antes de lograr dar la vuelta y cazar a la tortuga de nuevo. Podemos mejorar esto haciendo que las serpientes siempre giren cuando lleguen a la orilla del mundo.
(Esto además me da una oportunidad para enseñarte dos cosas: Podemos usar una sentencia if para tener un poco más de practica con esto, y tendremos una oportunidad para llamar métodos desde el objeto world.)

Girando a la orilla del mundo
Si queremos hacer que la serpiente gire a la orilla del mundo, primero debemos reconocer cuando estamos en la orilla. Podemos hacer esto definiendo un nuevo método llamado atWorldEdge que se encargue de revisar esto. Este método regresa un resultado Boolean: true si estamos cerca de la orilla, y false si no es así. El formato se ve así:
Entre este método, queremos escribir algo de código que exprese algo como esto:


  • Si estamos cerca del borde izquierdo o derecho, devuelve true.
  • Si estamos cerca del borde superior o inferior, devuelve true.
  • De otra forma, devuelve false.
Para la primera prueba mencionada aquí, necesitamos saber nuestra coordenada x. Para la segunda prueba, necesitamos nuestra coordenada y. Podemos obtener ambas usando los métodos getX() y getY() de la clase Actor. Estos dos métodos devuelven como su resultado nuestra posición actual.

Revisar si estamos en el borde izquierdo es bastante fácil, porque sabemos que la coordenada del borde izquierdo siempre es cero. Así que podemos escribir lo siguiente:
De hecho, queremos comenzar a girar no solo cuando demos con el borde, si no que cuando estemos cerca de él. Vamos a definir “cerca” en 10 pixeles. Así, podemos escribir lo siguiente: Eso trabajará bien. Revisar si estamos en el borde derecho, de todas formas, es un poco más complicado, porque la coordenada del borde derecho de un mundo puede variar.
Una opción es mirar en el código fuente de la clase TurtleWorld para ver el tamaño actual de nuestro mundo. Si hacemos esto, podemos ver que nuestro mundo tiene un tamaño de 600 x 400 pixeles, así que la posición más a la derecha posible está en la coordenada x 599.
Agregando nuevamente, un búfer de 10 pixeles, podemos ahora extender nuestra sentencia if desde arriba para además revisar el borde derecho:
La doble barra vertical (||) es un operador or (‘o’ en español), así que podemos leer esto de la siguiente forma (en español, el código claro que va en inglés, pero lo que sigue es pseudocódigo):
Esto va a trabajar para este mundo en particular, pero solo mientras no decidamos en algún punto cambiar el tamaño de nuestro mundo. Una mejor solución sería sólo llamar a un método y preguntarle qué tan ancho es el mundo.

Podemos hacer eso cambiando nuestra sentencia if a esto:
En esta condición, getWorld() llama a un método para que devuelva el objeto world en sí. Este objeto será devuelto desde esta llamada al método. Nosotros entonces llamamos a un segundo método getWidth(), en este objeto world.
Esta técnica es mucho mejor que poner el tamaño actual del mundo en nuestra clase, porque se adaptará flexiblemente a los cambios en el tamaño de nuestro mundo.
El método completo, después de que completamos la sentencia if y además añadimos otra para revisar la coordenada y se muestra a continuación:
Sentencias if/else
Otra nueva construcción que vemos en el código anterior es un ejemplo de una sentencia if/else. Ya hemos visto antes sentencias if, consisten de una condición y un cuerpo. El cuerpo fue ejecutado solo cuando la condición era true.
Esta nueva forma de la sentencia if tiene una palabra clave adicional, else, y un segundo bloque de código adjunto (ver el código de arriba). Este segundo bloque es ejecutado cuando la condición no es true.

Completando el giro
Ahora tenemos un método que nos permite revisar donde estamos cerca del borde del mundo. Lo siguiente que debemos hacer es girar si estamos al borde. Esto es ahora bastante fácil.
Añadimos una sentencia if a nuestro método moveAndTurn(), usando atWorldEdge como condición y giramos cuando notemos que estamos en el borde.

A continuación se muestra la nueva versión del método moveAndTurn() con esta mejora.
Intenta esto en tu propio scenario. Deberías notar que las serpientes ahora giran muy efectivamente una vez que llegan al borde del mundo.
Una lección importante
La lección más importante que aprendimos de esto es: El mundo es un objeto también, y tiene métodos útiles.
Podemos investigar los métodos del mundo de dos formas: Podemos solo llamarlos o también podemos leer su documentación.
Podemos llamar a un método del mundo dando click derecho a la imagen de fondo del mundo y seleccionando un método heredado del submenú mundo como se muestra a continuación:



Deberías intentar, por ejemplo, llamando a los métodos getWidth() y numberOfObjects() para ver lo que hacen.
Para investigar los métodos del mundo, leyendo su documentación, ve a la ventana principal de Greenfoot y selecciona Greenfoot Class Documentation del menú Help. Esto abre un explorador web con la documentación para todas las seis clases API. Selecciona la clase World y podrás ver una lista de métodos disponibles y sus descripciones.

Añadiendo sonido
Otra cosa que podemos hacer para mejorar nuestro pequeño juego es añadir efectos de sonido.
Descarga los archivos slurp.wav (slurp = sorber) y au.wav y guárdalos en tu carpeta del proyecto de la tortuga, ejemplo:  C:\Greenfoot\scenarios\turtle\sounds\.
La clase Greenfoot tiene un método estático playSound que toma el nombre y reproduce el sonido. Así que podemos reproducir el sonido slurp simplemente escribiendo lo siguiente:
Trata de añadir esta sentencia al código de tu tortuga, de manera que este sonido sea reproducido cuando la tortuga coma algo de pizza. A continuación se muestra el método eat() resultante: Si esto funciona, haz un cambio similar al código del actor Snake, de manera que la serpiente reproduzca el sonido au.wav cuando se coma la tortuga.


Grabando tus propios sonidos
Añadir efectos de sonido reproduciendo sonidos pregrabados es fácil, y eso añade un poco de diversión al proyecto. Pero podemos hacer esto aún mejor creando nuestros propios sonidos.
Mientras se pueden encontrar librerías de efectos de sonido gratuitas en el internet y usar los efectos descargados de ahí, por mucho la manera más fácil (y la más divertida) de añadir efectos es grabándolos tú mismo. Puedes hacer esto en cualquier computadora con un micrófono integrado.

Greenfoot tiene un grabador de sonidos integrado que hace realmente fácil hacer esto. Usando el menú principal, elige Show sound recorder desde el menú Controls. Esto traerá la interfaz del grabador de sonidos en una ventana separada como se muestra a continuación:



Este grabador de sonidos te permite grabar tu propia voz, o cualquier otro efecto de sonido, y recortarlo para eliminar sobresalientes no deseados o ruido de fondo o silencio. Puedes entonces guardar el sonido bajo el nombre de tu elección. Nota que Greenfoot siempre añadirá el sufijo .wav al nombre tu tu archivo.
Esto es importante porque se debe usar el nombre de archivo completo cuando se usa el sonido en tu código.
Por ejemplo, si se especifica “bark” como el nombre para tu sonido, Greenfoot nombrará el archivo como bark.wav, y podrás reproducirlo en el scenario usando la siguiente sentencia en tu código fuente:
Añadiendo tus propios efectos de sonido es una manera muy efectiva y muy fácil para personalizar tu scenario y hacerlo mucho más atractivo y divertido de jugar.


La clase Greenfoot
Aquí hay una lección general para llevar de esto: Vale la pena estar familiarizado con los métodos disponibles en la clase Greenfoot. Abre de nuevo la documentación de clase Greenfoot (como se describe arriba, usando la función del menú Help) y da un vistazo a los métodos disponibles en esta clase.
Tenemos ya usados algunos de ellos (para números aleatorios, control de teclado, y sonido), pero ahí hay otros que quizá encuentres útiles para hacer futuros cambios en tu propio scenario.

El API Greenfoot no es grande, y leer la documentación es tiempo bien gastado si planeas trabajar más con Greenfoot.
Tip: Maestros e instructores pueden encontrar mucho material de enseñanza en la comunidad de educadores Greenroom.


Conclusión
En este articulo, encontramos dos aspectos fundamentales de Java y la programación en Greenfoot:
El mundo en sí es un objeto Java. Tiene métodos que tú puedes llamar para interactuar con el mundo. Puedes usar la documentación del API Greenfoot para encontrar otros métodos existentes.
Greenfoot puede fácilmente grabar y reproducir sonidos. Esto hace a los scenarios de juego mucho más atractivos.
El método para reproducir un sonido está en la clase Greenfoot.

Bueno, eso es todo por hoy, ya me cansé de escribir, para la próxima entrada, la parte final de este gran proyecto, no se la pierdan, pueden suscribirse por email si quieren, en la parte superior derecha de esta página, comentarios, dudas, peticiones, criticas, abajo, con gusto doy respuesta, saludos a todos.


Traducción: El Blog De Baro.
Escrito por: Michael Kölling.
Fuente: Java Magazine.


Entradas Relacionadas:
Aprender Java creando un juego (Parte 6)
Aprender Java creando un juego (Parte 4)
Aprender Java creando un juego (Parte 3)
Aprender Java creando un juego (Parte 2)
Aprender Java creando un juego (Parte 1)


Comentarios