Planetalia - Java Training

Training and Consulting

Home

Tutorial - Writing a Space Invaders game in Java

  Previous Page - Getting Killed Current Page - 24 - The revenge of the Monsters   Next Page - A Scrolling playfield
  Return to the index of free Java tutorials  

The revenge of the Monsters

(c) Alexander Hristov

So far the monsters have beared with us slaughtering them without retaliation. In this step we add a firing behaviour to the monsters, so they can hit back, too.

We will define a new actor called "Laser" that will represent the thingies that the critters will shoot at us. We will use the following graphics for the laser, called disparo0.gif, disparo1.gif and disparo2.gif:

The Laser class is very similar to the Missile class. The only differences are the fact that the Laser has several frames, and a frame speed, and that it goes downwards and that it's slower than the missile:


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 version24;
10    
11    
12    public class Laser extends Actor {
13      protected static final int BULLET_SPEED=3;
14      
15      public Laser(Stage stage) {
16        super(stage);
17        setSpriteNames( new String[] {"disparo0.gif","disparo1.gif","disparo2.gif"});
18        setFrameSpeed(10);
19      }
20      
21      public void act() {
22        super.act();
23        y+=BULLET_SPEED;
24        if (y > Stage.PLAY_HEIGHT)
25          remove();
26      }
27    }
28    

Now we must make the monsters shoot randomly. We - rather arbitrarily - decide that in each turn, a monster has a 1% probability of firing. Considering that there are more than a hundred turns per second, this gives a rather decen firing rate. Actually, any frequency greater than that results in a laser shower. The process of firing is very similar to that of the player - a new actor (a Laser) is created and placed just below the monster that is firing:


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 version24;
10    
11    public class Monster extends Actor {
12      protected int vx;
13 protected static final double FIRING_FREQUENCY = 0.01;
14 15 public Monster(Stage stage) { 16 super(stage); 17 setSpriteNames( new String[] {"bicho0.gif","bicho1.gif"}); 18 setFrameSpeed(35); 19 } 20 21 public void act() { 22 super.act(); 23 x+=vx; 24 if (x < 0 || x > Stage.WIDTH) 25 vx = -vx;
26 if (Math.random()<FIRING_FREQUENCY) 27 fire();
28 } 29 30 public int getVx() { return vx; } 31 public void setVx(int i) {vx = i; } 32 33 public void collision(Actor a) { 34 if (a instanceof Bullet || a instanceof Bomb) { 35 remove(); 36 stage.getPlayer().addScore(20); 37 } 38 } 39
40 public void fire() { 41 Laser m = new Laser(stage); 42 m.setX(x+getWidth()/2); 43 m.setY(y + getHeight()); 44 stage.addActor(m); 45 }
46 } 47

And finally we must make the player react to collisions with lasers. For each hit, the shield will decrease 10 units:


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 version24;
10    
11    import java.awt.event.KeyEvent;
12    
13    public class Player extends Actor {
14      public static final int MAX_SHIELDS = 200;
15      public static final int MAX_BOMBS = 5;
16      protected static final int PLAYER_SPEED = 4;
17      protected int vx;
18      protected int vy;
19      private boolean up,down,left,right;
20      private int clusterBombs; 
21      private int score;
22      private int shields;
23        
24      
25      public Player(Stage stage) {
26        super(stage);
27        setSpriteNames( new String[] {"nave.gif"});
28        clusterBombs = MAX_BOMBS;
29        shields = MAX_SHIELDS;
30        score = 0;
31      }
32      
33      public void act() {
34        super.act();
35        x+=vx;
36        y+=vy;
37        if (x < 0 ) 
38          x = 0;
39        if (x > Stage.WIDTH - getWidth())
40          x = Stage.WIDTH - getWidth();
41        if (y < 0 )
42          y = 0;
43        if ( y > Stage.PLAY_HEIGHT-getHeight())
44          y = Stage.PLAY_HEIGHT - getHeight();
45      }
46    
47      public int getVx() { return vx; }
48      public void setVx(int i) {vx = i; }
49      public int getVy() { return vy; }
50      public void setVy(int i) {vy = i; }
51      
52      
53      protected void updateSpeed() {
54        vx=0;vy=0;
55        if (down) vy = PLAYER_SPEED;
56        if (up) vy = -PLAYER_SPEED;
57        if (left) vx = -PLAYER_SPEED;
58        if (right) vx = PLAYER_SPEED;
59      }
60      
61      public void keyReleased(KeyEvent e) {
62        switch (e.getKeyCode()) {
63          case KeyEvent.VK_DOWN : down = false;break;
64          case KeyEvent.VK_UP : up = false; break;
65          case KeyEvent.VK_LEFT : left = false; break; 
66          case KeyEvent.VK_RIGHT : right = false;break;
67        }
68        updateSpeed();
69      }
70      
71      public void keyPressed(KeyEvent e) {
72        switch (e.getKeyCode()) {
73          case KeyEvent.VK_UP : up = true; break;
74          case KeyEvent.VK_LEFT : left = true; break;
75          case KeyEvent.VK_RIGHT : right = true; break;
76          case KeyEvent.VK_DOWN : down = true;break;
77          case KeyEvent.VK_SPACE : fire(); break;
78          case KeyEvent.VK_B : fireCluster(); break;
79        }
80        updateSpeed();
81      }
82      
83      public void fire() {
84        Bullet b = new Bullet(stage);
85        b.setX(x);
86        b.setY(y - b.getHeight());
87        stage.addActor(b);
88      }
89      
90      public void fireCluster() {
91        if (clusterBombs == 0)
92          return;
93          
94        clusterBombs--;
95        stage.addActor( new Bomb(stage, Bomb.UP_LEFT, x,y));
96        stage.addActor( new Bomb(stage, Bomb.UP,x,y));
97        stage.addActor( new Bomb(stage, Bomb.UP_RIGHT,x,y));
98        stage.addActor( new Bomb(stage, Bomb.LEFT,x,y));
99        stage.addActor( new Bomb(stage, Bomb.RIGHT,x,y));
100       stage.addActor( new Bomb(stage, Bomb.DOWN_LEFT,x,y));
101       stage.addActor( new Bomb(stage, Bomb.DOWN,x,y));
102       stage.addActor( new Bomb(stage, Bomb.DOWN_RIGHT,x,y));
103     }
104     
105     public int getScore() {   return score; }
106     public void setScore(int i) { score = i;  }
107     public void addScore(int i) { score += i;  }
108   
109     public int getShields() { return shields; }
110     public void setShields(int i) { shields = i;  }
111     public void addShields(int i) {
112       shields += i;
113       if (shields > MAX_SHIELDS) shields = MAX_SHIELDS;
114     }
115     
116     public void collision(Actor a) {
117       if (a instanceof Monster ) {
118         a.remove();
119         addScore(40);
120         addShields(-40);
121       }
122 if (a instanceof Laser ) { 123 a.remove(); 124 addShields(-10);
125 } 126 if (getShields() < 0) 127 stage.gameOver(); 128 } 129 130 public int getClusterBombs() { return clusterBombs; } 131 public void setClusterBombs(int i) { clusterBombs = i; } 132 133 } 134

Space Invaders Tutorial in Java



Do you want to be notified when new tutorials or lessons are published? Press here


Full list of Java source files for this step

Actor.java Bomb.java Bullet.java Invaders.java
Laser.java Monster.java Player.java SpriteCache.java
Stage.java      

Full list of resources

bicho.gif bicho0.gif bicho1.gif bicho2.gif
bombD.gif bombDL.gif bombDR.gif bombL.gif
bombR.gif bombU.gif bombUL.gif bombUR.gif
disparo.gif disparo0.gif disparo1.gif disparo2.gif
explosion.wav misil.gif missile.wav musica.wav
nave.gif oceano.gif photon.wav test.gif
Thumbs.db      

  Previous Page - Getting Killed Current Page - 24 - The revenge of the Monsters   Next Page - A Scrolling playfield
  Return to the index of free Java tutorials  

(c) 2004 Planetalia S.L. All rights reserved. Unauthorized reproduction and/or mirroring is not permitted