GameOver y Reset

Autocolisión

Después de que podamos desplegar de forma correcta el cuerpo de la serpiente, y corrijamos la media vuelta, es tiempo de crear la colisión con el mismo cuerpo de la serpiente. Para esto, copiaremos estas líneas en la función game:

				//	Colisión con el serpiente
				for (int i = 2; i < longitud; i++)
				{
					if (serpiente[0].x == serpiente[i].x && serpiente[0].y == serpiente[i].y)
					{
						PAUSE = true;
					}
				}

Como podemos ver, comparamos todas las partes del cuerpo a partir del dos, obviamente únicamente con su longitud, y si llega a colisionar con la cabeza, el juego se pondrá en pausa. Pero este indicador no será suficiente, pues tambien debemos saber la diferecia de cuando el juego está en pausa y cuando se ha perdido. Esto podemos corregirlo creando una segunda variable booleana:

	boolean gameover;

No especifico que se inicie como falsa, pues es su valor predeterminado. Ahora agregamos dentro de la misma colisión, debajo de donde el juego se pausa, que el gameover tambien se haga verdadero:

						gameover = true;

Y cambiemos el paint para que tambien nos indique cuando estamos en estado de gameover o solo en pausa:

		if (gameover)
		{
			g.drawString("GAME OVER", this.getWidth()/2-30, this.getHeight()/2);
		}
		else if (PAUSE)
		{
			g.drawString("PAUSA", this.getWidth()/2-20, this.getHeight()/2);
		}

Con la ayuda del "else if", le indicamos que la segunda opción solo la haga si la primera no fue cierta. Probemos el juego con Shift+F6 y podremos ver que efectivamente, al chocar contra nuestro cuerpo, el juego se pausa y nos muestra un signo que dice "Game Over".

Reiniciando el juego

Seguramente has notado que al quitar la pausa, el juego sigue como si nada hubiera pasado. Esto se debe a que sabemos que el juego ha terminado, pero no que hacer después de esto. Para esto, comenzaremos por crear una nueva función de nombre "reset", que reiniciará todos los valores a como deseamos estén al principio. He aquí un ejemplo de ello:

	public void reset()
	{
		serpiente[0].x=50;
		serpiente[0].y=50;
		direccion = 1;
		longitud = 3;
		manzana.x = (int)(Math.random() * (this.getWidth()/10 - 1)) * 10;
		manzana.y = (int)(Math.random() * (this.getHeight()/10 - 2)) * 10 + 10;
		gameover = false;
	}

Ahora, llamaremos a la función en el momento necesario, para esto, modificaremos nuestra función teclado:

			case Event.ENTER:
				PAUSE = !PAUSE;
				if (gameover)
				{
					reset();
				}
				break;

Conviene tambien llamar al reset al final del init, así el juego siempre tendrá los valores predeterminados, y solo tendremos que modificar el reset para cambiarlos. Hasta el momento, tu código debe verse como a continuación:

import GameLib.Game;
import java.awt.Graphics;
import java.awt.Color;
import java.awt.Point;
import java.awt.Event;

public class snake extends Game
{
	// Aquí se declaran nuestras variables
	boolean PAUSE = true;
	int maxlong = 500;
	Point serpiente[] = new Point[maxlong];
	Point manzana = new Point (100, 100);
	int direccion = 1;
	int longitud = 1;
	boolean gameover;
	
	public void init()
	{
		// Comienza descarga asíncrona de recursos pesados
		setBackground(Color.black);
		for (int i = 0; i < maxlong; i++)
		{
			serpiente[i] = new Point(0, 0);
		}
		reset();
	}
	
	public void reset()
	{
		serpiente[0].x=50;
		serpiente[0].y=50;
		direccion = 1;
		longitud = 3;
		manzana.x = (int)(Math.random() * (this.getWidth()/10 - 1)) * 10;
		manzana.y = (int)(Math.random() * (this.getHeight()/10 - 2)) * 10 + 10;
		gameover = false;
	}

	public void game()
	{
		// Aquí va el código de nuestro juego
		if (!PAUSE)
		{
			//	Se mueve el serpiente
			for (int i = longitud; i > 0; i--)
			{
				serpiente[i].x = serpiente[i-1].x;
				serpiente[i].y = serpiente[i-1].y;
			}
				
			//	Se mueve el serpiente[0]
			switch	(direccion)
			{
				case 0:
					serpiente[0].y -= 10;
					break;
				case 1:
					serpiente[0].x += 10;
					break;
				case 2:
					serpiente[0].y += 10;
					break;
				case 3:
					serpiente[0].x -= 10;
					break;
			}
			
			//	Salida del escenario
			if (serpiente[0].x < 0)
			{
				serpiente[0].x = this.getWidth()-10;
			}
			if (serpiente[0].x > this.getWidth()-10)
			{
				serpiente[0].x = 0;
			}
			if (serpiente[0].y < 10)
			{
				serpiente[0].y = this.getHeight()-10;
			}
			if (serpiente[0].y > this.getHeight()-10)
			{
				serpiente[0].y = 10;
			}
			
			//	Colisión serpiente[0]-Manzana
			if (serpiente[0].x == manzana.x && serpiente[0].y == manzana.y)
			{
				longitud += 1;
				manzana.x = (int)(Math.random() * (this.getWidth()/10 - 1)) * 10;
				manzana.y = (int)(Math.random() * (this.getHeight()/10 - 2)) * 10 + 10;
			}
				
				//	Colisión con el serpiente
				for (int i = 2; i < longitud; i++)
				{
					if (serpiente[0].x == serpiente[i].x && serpiente[0].y == serpiente[i].y)
					{
						PAUSE = true;
						gameover = true;
					}
				}
		}
	}
	
	public void paint(Graphics g)
	{
		// Aquí se dibujan todos los objetos
		g.clearRect(0, 0, this.getWidth(), this.getHeight());
		g.setColor(Color.green);
		for (int i = 0; i < longitud; i++)
		{
			g.drawOval(serpiente[i].x, serpiente[i].y, 10, 10);
		}
		g.setColor(Color.red);
		g.drawOval(manzana.x, manzana.y, 10, 10);
		g.setColor(Color.white);
		g.drawString("Longitud: " + longitud, 10, 10);
		if (gameover)
		{
			g.drawString("GAME OVER", this.getWidth()/2-30, this.getHeight()/2);
		}
		else if (PAUSE)
		{
			g.drawString("PAUSA", this.getWidth()/2-20, this.getHeight()/2);
		}
	}
	
	public boolean keyDown(Event e, int key)
	{
		switch(key)
		{
			//	Cambia el rumbo de la serpiente
			case Event.UP:
				if (direccion != 2)
				{
					direccion = 0;
				}
				break;
			case Event.RIGHT:
				if (direccion != 3)
				{
					direccion = 1;
				}
				break;
			case Event.DOWN:
				if (direccion != 0)
				{
					direccion = 2;
				}
				break;
			case Event.LEFT:
				if (direccion != 1)
				{
					direccion = 3;
				}
				break;
			case Event.ENTER:
				PAUSE = !PAUSE;
				if (gameover)
				{
					reset();
				}
				break;
		}
		return true;
	}
}

Ahora, probemos el código con Shift+F6 y comprobemos que todo esté funcionando de forma correcta. ¡Felicidades! Acabas de terminar de programar tu primer juego. Muchas gracias por tomar este curso y espero te hayas divertido con él. A continuación, mostramos como debe verse el juego final:

Hmm... Me pregunto si seré solo yo, o hay un pequeño detalle que aun debe ser corregido...

[Un proyecto de Ayotli Diseño Web]