Imágenes y sonidos

Puedes ver los archivos usados en este tutorial siguiendo este enlace: media/

Imágenes

Incluir imágenes no es complicado. Lo que es importante antes de incluirlas, es saber que el tamaño de la imagen es totalmente independiente del tamaño de nuestro rectángulo. Así, si nuestra imagen es de 40px y nuestro rectángulo de 10px, o a la inversa, nuestra imagen es de 20px y nuestro rectángulo de 50px, es muy posible que obtengamos colisiones inesperadas y otros errores en el desarrollo de nuestro juego.

Por eso es importante crear todo nuestro juego sin imágenes, y una vez acabado, incluirlas en la última compilación, asegurándonos siempre que las imágenes sean del mismo tamaño que los rectángulos correspondientes.

Ahora advertidos de esto, incluyamos nuestras imágenes en el juego final. Comencemos por importar la librería de imágenes:

import java.awt.Image;

A continuación crearemos las variables para nuestras imágenes:

	Image iSerpiente, iManzana;

Y obtenemos los archivos desde la carpeta local "media":

		iSerpiente = this.getImage (this.getCodeBase(), "media/body.png");
		iManzana = this.getImage (this.getCodeBase(), "media/apple.png");

Tanto body.png como apple.png son archivos de imágenes de 10x10 pixeles. Recuerda que es importante que las imágenes midan el tamaño del rectángulo. Para crearlas, puedes usar cualquier editor de gráficos, nosotros las hicimos en paint.

Finalmente, pasaremos a dibujarlas en el Paint, comentando las líneas equivalentes donde dibujábamos los círculos que indicaban la posición de nuestros objetos:

		//g.setColor(Color.green);
		for (int i = 0; i < longitud; i++)
		{
			//g.drawOval(serpiente[i].x, serpiente[i].y, serpiente[i].width, serpiente[i].height);
			g.drawImage(iSerpiente, serpiente[i].x, serpiente[i].y, this);
		}
		//g.setColor(Color.red);
		//g.drawOval(manzana.x, manzana.y, manzana.width, manzana.height);
		g.drawImage(iManzana, manzana.x, manzana.y, this);

Si lo haz hecho de forma correcta, al actualizar el archivo verás las imágenes en lugar de los aros que antes se mostraban.

Intenta ahora poner una imagen de fondo del mismo tamaño del applet, creando una variable iFondo para ello, y dibujándole en lugar del clearRect:

		//g.clearRect(0, 0, this.getWidth(), this.getHeight());
		g.drawImage(iFondo, 0, 0, this);

Sonidos

Ahora que nuestro juego tiene imágenes, será bueno que también incluyamos algunos efectos de sonido. Puedes buscar varios en Internet. En este caso, solo usaremos uno para hacer el sonido de la serpiente comiendo la manzana, y otro para cuando la serpiente se muerda a si misma (Game Over). Importemos la librería para Audioclips:

import java.applet.AudioClip;

Después, declaremos nuestras variables de Audioclip:

	AudioClip aComer, aMorir;

Y obtengamos los archivos desde la carpeta local "media":

		aComer = this.getAudioClip (this.getCodeBase(), "media/chomp.au");
		aMorir = this.getAudioClip (this.getCodeBase(), "media/dies.au");

Para reproducir el sonido, solo debemos llamar a la función play() del audioclip. En este caso, lo haremos cuando la serpiente come una manzana, y cuando choca contra si misma, con sus sonidos respectivos:

			//	Colisión serpiente[0]-Manzana
			if (serpiente[0].intersects(manzana))
			{
				if (longitud < maxlong)
					longitud += 1;
				aComer.play();
				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].intersects(serpiente[i]))
				{
					PAUSE = true;
					gameover = true;
					aMorir.play();
				}
			}

Con esto, el juego tendrá imágenes y sonidos. Presionemos Shift+F6 para probarlo, tu código final debería quedar de esta forma:

import jge.Game;
import java.awt.Graphics;
import java.awt.Color;
import java.awt.Rectangle;
import java.awt.Event;
import java.awt.Image;
import java.applet.AudioClip;

public class snake extends Game
{
	// Aquí se declaran nuestras variables
	boolean PAUSE = true;
	int maxlong = 500;
	Rectangle serpiente[] = new Rectangle[maxlong];
	Rectangle manzana = new Rectangle (100, 100, 10, 10);
	int direccion = 1;
	int longitud = 1;
	boolean gameover;
	boolean leible;
	Image iSerpiente, iManzana, iFondo;
	AudioClip aComer, aMorir;
	
	public void init()
	{
		// Comienza descarga asíncrona de recursos pesados
		this.setSize(350, 200);
		this.setBackground(Color.black);

		iSerpiente = this.getImage (this.getCodeBase(), "media/body.png");
		iManzana = this.getImage (this.getCodeBase(), "media/apple.png");
		iFondo = this.getImage(this.getCodeBase(), "media/grass1.png");
		aComer = this.getAudioClip (this.getCodeBase(), "media/chomp.au");
		aMorir = this.getAudioClip (this.getCodeBase(), "media/dies.au");

		for (int i = 0; i < maxlong; i++)
		{
			serpiente[i] = new Rectangle(0, 0, 10, 10);
		}
		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;
			}
			leible = true;
			
			//	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].intersects(manzana))
			{
				if (longitud < maxlong)
					longitud += 1;
				aComer.play();
				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].intersects(serpiente[i]))
				{
					PAUSE = true;
					gameover = true;
					aMorir.play();
				}
			}
		}
	}
	
	public void paint(Graphics g)
	{
		// Aquí se dibujan todos los objetos
		//g.clearRect(0, 0, this.getWidth(), this.getHeight());
		g.drawImage(iFondo, 0, 0, this);
		//g.setColor(Color.green);
		for (int i = 0; i < longitud; i++)
		{
			//g.drawOval(serpiente[i].x, serpiente[i].y, serpiente[i].width, serpiente[i].height);
			g.drawImage(iSerpiente, serpiente[i].x, serpiente[i].y, this);
		}
		//g.setColor(Color.red);
		//g.drawOval(manzana.x, manzana.y, manzana.width, manzana.height);
		g.drawImage(iManzana, manzana.x, manzana.y, this);
		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 && leible)
				{
					direccion = 0;
					leible = false;
				}
				break;
			case Event.RIGHT:
				if (direccion != 3 && leible)
				{
					direccion = 1;
					leible = false;
				}
				break;
			case Event.DOWN:
				if (direccion != 0 && leible)
				{
					direccion = 2;
					leible = false;
				}
				break;
			case Event.LEFT:
				if (direccion != 1 && leible)
				{
					direccion = 3;
					leible = false;
				}
				break;
			case Event.ENTER:
				PAUSE = !PAUSE;
				if (gameover)
				{
					reset();
				}
				break;
		}
		return true;
	}
}

Y el juego debe de verse así:

[Un proyecto de Ayotli Diseño Web]