INTRODUCCIÓN:
Ahora que disponemos de dos sprites nada mejor que detectar cuando ambos colisionan, para esto añadimos un nuevo método llamado collision cuyo unico parámetro será un objeto de tipo Sprite y su valor de retorno sera un valor booleano que nos indicara si hubo o no colision con el objeto sprite pasado por parametro.
Por motivos prácticos modificaremos la clase Sprite donde además de añadir el método collision quitaremos los atributos y métodos utilizados por el Sprite player (nuetro sprite que controlamos con el teclado) y crearemos una nueva clase llamada Player la cual será una extensión de la clase Sprite y dentro de esta clase colocaremos los atributos y métodos que hemos quitado de la clase sprite.
Clases que intervendrán en el siguiente ejemplo:
- Demo1
- SSCanvas
- Sprite
- Player
Aqui el código completo, más abajo se analizará los cambios añadidos
//importamos las clases de java que utilizaremos en nuestro programa
import javax.microedition.midlet.*;
import javax.microedition.lcdui.*;
/*aqui nuestro MIDlet, esta clase sera la primera en ser ejecutada cuando se
ejecute el programa*/
public class Demo1 extends MIDlet {
//metodo cuando el midlet arranca
public void startApp() {
//creamos un objeto SSCanvas (nuestra pantalla de juego)
SSCanvas screen=new SSCanvas();
//indicamos al dispositivo que screen (instancia de SSCanvas) será la
//nueva pantalla activa
Display.getDisplay(this).setCurrent(screen);
new Thread(screen).start(); //arrancamos el bucle (nuevo hilo de ejecución)
}
//metodo cuando el midlet entra en pausa
public void pauseApp() {
}
//metodo cuando el midlet es destruido
public void destroyApp(boolean unconditional) {
}
}
//esta clase es la encargada de hacer funcionar nuestra aplicación gráfica
class SSCanvas extends Canvas implements Runnable{
private Sprite ball;
private Player player;
//metodo constructor
public SSCanvas(){
//instanciamos (creamos) el objeto ball a partir de la clase Sprite
ball = new Sprite(getWidth()/2,getHeight()/2,20,20);
player = new Player(getWidth()/2,getHeight()/3,30,30);
}
public void run(){
while(true){
//actualizamos la posicion de la bola
ball.compute(getWidth(),getHeight());
player.computePlayer(getWidth(),getHeight());
//forzamos el repintado de la pantalla
repaint();
serviceRepaints();
try {
Thread.sleep(30);
} catch (InterruptedException e) {
}
}
}
//metodo de la clase canvas para pintar en pantalla
public void paint(Graphics g){
//seleccionamos el color negro para pintar el fondo
if(ball.collision(player))g.setColor(200,0,0);
else g.setColor(0,0,0);
//pintamos el fondo de pantalla con un rectangulo con el tamaño de
//la pantalla getWidth() y getHeight() es un método de la clase canvas
//que nos devuelve el ancho y alto de la pantalla
g.fillRect(0,0,getWidth(),getHeight());
//pintamos la bola en pantalla
ball.draw(g);
player.draw(g);
}
/*sobrecarga de método para detectar cuando una tecla es soltada
por el usuario*/
public void keyReleased(int keyCode) {
int action=getGameAction(keyCode);
switch (action) {
case LEFT:
player.keyUp(player.LEFT);
break;
case RIGHT:
player.keyUp(player.RIGHT);
break;
case UP:
player.keyUp(player.UP);
break;
case DOWN:
player.keyUp(player.DOWN);
break;
case FIRE:
break;
}
}
//sobrecarga del método que detecta cuando una tecla es pulsada por el usuario
public void keyPressed(int keyCode) {
int action=getGameAction(keyCode);
switch (action) {
case LEFT:
player.keyPress(player.LEFT);
break;
case RIGHT:
player.keyPress(player.RIGHT);
break;
case UP:
player.keyPress(player.UP);
break;
case DOWN:
player.keyPress(player.DOWN);
break;
case FIRE:
break;
}
}
}
class Sprite{
//atributos privados
protected int x;
protected int y;
protected int width;
protected int height;
protected int incX,incY;
//metodo constructor
public Sprite(int x,int y,int width,int height){
this.x=x;
this.y=y;
this.width=width;
this.height=height;
incX=3;
incY=3;
}
//metodo que actualiza la posición del sprite
public void compute(int screenW, int screenH){
if(x <= 0)incX=3;
else if(x+width >= screenW)incX=-3;
x+=incX;
}
//metodo que muestra en pantalla al sprite
public void draw(Graphics g){
g.setColor(250,0,0);
g.fillArc(x,y, width, height,0, 360);
}
//metodo para detectar colisiones
public boolean collision(Sprite sp){
//comprobamos si el sprite 1 ha colisionado o
//superpuesto sobre el sprite 2
if (((x+width)>sp.x)&&((y+height)>sp.y)&&
((sp.x+sp.width)>x)&&((sp.y+sp.height)>y)){
return true;
}else{
return false;
}
}
}
class Player extends Sprite{
private boolean startX=false;
private boolean startY=false;
//declaracion de constantes
protected static final int LEFT = 1;
protected static final int RIGHT = 2;
protected static final int UP = 3;
protected static final int DOWN = 4;
protected static final int FIRE = 5;
public Player(int x,int y,int width,int height){
super(x,y,width,height);
}
//metodo que actualiza la posicion del sprite
public void computePlayer(int screenW, int screenH) {
if(x + incX > 0 && (x + incX) < (screenW - width)){
x+=incX;
if(startX==false)incX=0;
}
if(y + incY > 0 && (y + incY) < (screenH - height)){
y+=incY;
if(startY==false)incY=0;
}
}
//metodo para detener el desplazamiento del sprite
public void keyUp(int keyCode) {
switch (keyCode) {
case LEFT:
startX=false;
break;
case RIGHT:
startX=false;
break;
case UP:
startY=false;
break;
case DOWN:
startY=false;
break;
}
}
//método para indicar la dirección del desplazamiento
public void keyPress(int keyCode) {
switch (keyCode) {
case LEFT:
incX=-5;
startX=true;
break;
case RIGHT:
incX=5;
startX=true;
break;
case UP:
incY=-5;
startY=true;
break;
case DOWN:
incY=5;
startY=true;
break;
case FIRE:
break;
}
}
}
EXPLICACION DEL CÓDIGO (solo se explicara los cambios, osea lo resaltado en verde)
Clase Demo1: No sufre ningún cambio a la versión de la tutorial anterior
Clase SSCanvas: Se modifica el tipo de objeto para player pasando de Sprite a Player, se llama al método collision del objeto ball desde el método paint con una condicional que si nos retorna verdadero (que hubo colision entre ball y el player) cambiamos el color de fondo.
Clase Sprite: Aqui quitamos los atributos y métodos que era utilizados exclusivamente por el player (nuetro sprite controlado por teclado) y añadimos un nuevo método para poder detectar colisiones con otros Sprites.
Clase Player: Se añade esta nueva clase que servira exclusivamente para el jugador controlado por teclado los metodos y atributos que lo componen fueron quitados de la clase Sprite, además Player es una extension de Sprite con lo cual además de tener sus propios atributos y métodos dispone de los atributos y métodos de la clase Sprite.
EXPLICACIÓN DEL CÓDIGO LINEA A LINEA
//metodo para detectar colisiones
public boolean collision(Sprite sp){
//comprobamos si el sprite 1 ha colisionado o
//superpuesto sobre el sprite 2
if (((x+width)>sp.x)&&((y+height)>sp.y)&&
((sp.x+sp.width)>x)&&((sp.y+sp.height)>y)){
return true;
}else{
return false;
}
}
class Player extends Sprite{
Para ver el programa en acción copia y pega el código como se explica en la tutorial 2.