Training and Consulting | ||
| Home |
| Previous Page - More shooting - Cluster bombs | Current Page - 20 - Collision detection | Next Page - Status |
| Return to the index of free Java tutorials |
Collision detectionSo far our critters have been laughing in our face because of our inability to kill them regardless of our powerful list of weapons. It's about time to add collision detection to our program. Collision detection can be made as hard or as easy as one wishes. The standard way in 2D games to perform collision detection is to check if the bounding rectangles of the two objects intersect (overlap):
In order to maintain maximum flexibility for the future, we want to check if any two actors collide. This requires handling the global list of actors, and as such, must be done by the Invaders class, since the global list is its responsability Fortunately, all Java classes that implement Shape (and Rectangle is one of them) include an intersects() method that allows us to check if the shape intersects with a given rectangle. Since we will be checking for collisions all actors, this means that we will need periodically to obtain the bounding rectangle of any of them. The best approach would be to code a method (for example getBounds()) in the Actor class.
. . .
79
80 public Rectangle getBounds() {
81 return new Rectangle(x,y,width,height);
82 }
83
. . .
Ok, so now we know how to detect a collision. And then what happens? Again we will make use of polymorphism and a very common pattern called responsability delegation : whenver a collision between two actors is detected, each of them is notified and each acts in whatever way it chooses. This means that there will be a new method in the Actor class called collision(...). This method will be called whenever the affected actor collides with something, and the main class will pass as a parameter the actor with which it has collided. By default this method will do nothing, and those who extend the base class will override it to suit their needs :
. . .
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
Of course we would like the critters to die whenever they are hit by a missile or bomb. This will be handled in the newly defined method: 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 And finally we must code the loops in the main class that will check whether any collisions have occurred. The new method that will perform these checks will be 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 |
||||||||||||||||||||||||||
Do you want to be notified when new tutorials or lessons are published? Press here
| Actor.java | Bomb.java | Bullet.java | Invaders.java |
| Monster.java | Player.java | SpriteCache.java | Stage.java |
| Previous Page - More shooting - Cluster bombs | Current Page - 20 - Collision detection | Next Page - Status |
| Return to the index of free Java tutorials |
(c) 2004 Planetalia S.L. All rights reserved. Unauthorized reproduction and/or mirroring is not permitted