Cursos y Másters | ||
| Inicio Profesores Aulas Testimonios Cursos Masters Tecnologías Cursos Gratuitos Galería de Proyectos Solicitar Información |
| Página Anterior - Más disparos - Bombas de fragmentación | Página Actual - 20 - Detección de colisiones | Página Siguiente - Barra de estado |
| Índice de cursos Java gratuitos |
Detección de colisionesHasta ahora los monstruos se habían reido en nuestra cara de nuestros disparos porque ninguno de ellos les afectaba lo más mínimo. Ha llegado la hora de añadir la detección de colisiones a nuestro programa. En general es erróneo plantearse la detección de colisiones como un asunto de objetos puntuales, ya que nuestros sprites tienen tanto anchuras como alturas. De esta forma, habrá una colisión cuando los rectángulos que encierran cada sprite se intersecten:
Esta comprobación habrá que hacerla para todas las posibles parejas de actores, y además habrá que hacerla para cada actor con el jugador. Esta comprobación puesto que involucra manejar la lista global de actores, la debe hacer la clase Invaders Afortunadamente, la clase Rectangle de Java incorpora el método intersects() que permite comprobar si un rectángulo intersecta con otro. Como necesitaremos saber los rectángulos que engloban cada sprite, podemos añadir un método (por ejemplo getBounds()) en la clase Actor que ya devuelva el objeto Rectangle construido. Cuando detectamos una colisión, ¿qué es lo que hay que hacer?. De nuevo echamos mano del polimorfismo y de la delegación de responsabilidades y lo que haremos será limitarnos a notificar a cada actor que se ha producido una colisión con otro actor, y que ellos decidan lo que hacer en consecuencia. Esto significa que aparece un nuevo método en la clase Actor llamado collision(...). Por defecto este método no hace nada, siendo las clases hijas las responsables de sobreescribirlo como buenamente crean oportuno:
. . .
79
80 public Rectangle getBounds() {
81 return new Rectangle(x,y,width,height);
82 }
83
84 public void collision(Actor a){
85
86 }
87 }
88
Lógicamente, queremos que los monstruos mueran cuando ocurre una colisión con un misil o una bomba. Esto se realiza de la siguiente forma en la clase Monster:
1 /** 2 * Curso B?sico de desarrollo de Juegos en Java - Invaders 3 * 4 * (c) 2004 Planetalia S.L. - Todos los derechos reservados. Prohibida su reproducci?n 5 * 6 * http://www.planetalia.com 7 * 8 */ 9 package version20; 10 11 public class Monster extends Actor { 12 protected int vx; 13 14 public Monster(Stage stage) { 15 super(stage); 16 setSpriteNames( new String[] {"bicho0.gif","bicho1.gif"}); 17 setFrameSpeed(35); 18 } 19 20 public void act() { 21 super.act(); 22 x+=vx; 23 if (x < 0 || x > Stage.WIDTH) 24 vx = -vx; 25 } 26 27 public int getVx() { return vx; } 28 public void setVx(int i) {vx = i; } 29 Y finalmente queda la propia detección de colisiones, que se realiza en la clase principal, en un nuevo método al que hemos llamado checkCollisions():
1 package version20; 2 /** 3 * Curso B?sico de desarrollo de Juegos en Java - Invaders 4 * 5 * (c) 2004 Planetalia S.L. - Todos los derechos reservados. Prohibida su reproducci?n 6 * 7 * http://www.planetalia.com 8 * 9 */ 10 11 12 import java.awt.Canvas; 13 import java.awt.Color; 14 import java.awt.Dimension; 15 import java.awt.Graphics2D; 16 import java.awt.Rectangle; 17 import java.awt.event.KeyEvent; 18 import java.awt.event.KeyListener; 19 import java.awt.event.WindowAdapter; 20 import java.awt.event.WindowEvent; 21 import java.awt.image.BufferStrategy; 22 import java.util.ArrayList; 23 24 import javax.swing.JFrame; 25 import javax.swing.JPanel; 26 27 public class Invaders extends Canvas implements Stage, KeyListener { 28 29 private BufferStrategy strategy; 30 private long usedTime; 31 32 private SpriteCache spriteCache; 33 private ArrayList actors; 34 private Player player; 35 36 public Invaders() { 37 spriteCache = new SpriteCache(); 38 39 40 JFrame ventana = new JFrame("Invaders"); 41 JPanel panel = (JPanel)ventana.getContentPane(); 42 setBounds(0,0,Stage.WIDTH,Stage.HEIGHT); 43 panel.setPreferredSize(new Dimension(Stage.WIDTH,Stage.HEIGHT)); 44 panel.setLayout(null); 45 panel.add(this); 46 ventana.setBounds(0,0,Stage.WIDTH,Stage.HEIGHT); 47 ventana.setVisible(true); 48 ventana.addWindowListener( new WindowAdapter() { 49 public void windowClosing(WindowEvent e) { 50 System.exit(0); 51 } 52 }); 53 ventana.setResizable(false); 54 createBufferStrategy(2); 55 strategy = getBufferStrategy(); 56 requestFocus(); 57 addKeyListener(this); 58 } 59 60 public void initWorld() { 61 actors = new ArrayList(); 62 for (int i = 0; i < 10; i++){ 63 Monster m = new Monster(this); 64 m.setX( (int)(Math.random()*Stage.WIDTH) ); 65 m.setY( i*20 ); 66 m.setVx( (int)(Math.random()*20-10) ); 67 68 actors.add(m); 69 } 70 71 player = new Player(this); 72 player.setX(Stage.WIDTH/2); 73 player.setY(Stage.HEIGHT - 2*player.getHeight()); 74 } 75 76 public void addActor(Actor a) { 77 actors.add(a); 78 } 79 80 public void updateWorld() { 81 int i = 0; 82 while (i < actors.size()) { 83 Actor m = (Actor)actors.get(i); 84 if (m.isMarkedForRemoval()) { 85 actors.remove(i); 86 } else { 87 m.act(); 88 i++; 89 } 90 } 91 player.act(); 92 } 93 |
||||||||||||||||||||
¿Quieres ser notificado cuando salan nuevos tutoriales y cursos?. Pulsa aquí
| Actor.java | Bomb.java | Bullet.java | Invaders.java |
| Monster.java | Player.java | SpriteCache.java | Stage.java |
| Página Anterior - Más disparos - Bombas de fragmentación | Página Actual - 20 - Detección de colisiones | Página Siguiente - Barra de estado |
| Índice de cursos Java gratuitos |
(c) 2004 Planetalia S.L. Todos los derechos reservados. Prohibida su reproducción