Planetalia - Java Training

Training and Consulting

Home

Tutorial - Writing a Space Invaders game in Java

  Previous Page - The Player Current Page - 17 - Controlling the player   Next Page - Shots
  Return to the index of free Java tutorials  

Controlling the player

(c) Alexander Hristov

Our previous version of the game showed the player's spaceship but did not allow to control it. In this version we will add this possibility. The ship will be controlled using the cursor keys. Pressing (and holding) the "left" key for example will make the ship move leftwards, in adition to any vertical movement that it might already have. This means that if the user presses simultaneously up and left, the ship will move both upwards and leftwards.

Although we could handle all this in the Invaders, it is more appropriate and more flexible to delegate the event handling to the Player class. The approach we will be following will thus be:

  1. The Invaders class will receive all keyboard events.
  2. When an event arrives, the class will first process the keys that affect the generic game state, such as "Pause", "Exit", "Restart", etc.. We still don't have such options, but we would like to have this possibility in the future, and this is the reason for the events arriving first at this class instead of sending them directly to the player.
  3. If the key is none of the generic keys, the event is passed to the Player class so that it can act in whatever way it wishes

We'll define two new methods in Player called keyPressed(...) and keyReleased(...). These methods will mirror the standard keyboard event methods.

So now we have our main class as follows:


1     package version17;
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.event.KeyEvent;
17    import java.awt.event.KeyListener;
18    import java.awt.event.WindowAdapter;
19    import java.awt.event.WindowEvent;
20    import java.awt.image.BufferStrategy;
21    import java.util.ArrayList;
22    
23    import javax.swing.JFrame;
24    import javax.swing.JPanel;
25    
26 public class Invaders extends Canvas implements Stage, KeyListener {
27 28 private BufferStrategy strategy; 29 private long usedTime; 30 31 private SpriteCache spriteCache; 32 private ArrayList actors; 33 private Player player; 34 35 public Invaders() { 36 spriteCache = new SpriteCache(); 37 38 39 JFrame ventana = new JFrame("Invaders"); 40 JPanel panel = (JPanel)ventana.getContentPane(); 41 setBounds(0,0,Stage.WIDTH,Stage.HEIGHT); 42 panel.setPreferredSize(new Dimension(Stage.WIDTH,Stage.HEIGHT)); 43 panel.setLayout(null); 44 panel.add(this); 45 ventana.setBounds(0,0,Stage.WIDTH,Stage.HEIGHT); 46 ventana.setVisible(true); 47 ventana.addWindowListener( new WindowAdapter() { 48 public void windowClosing(WindowEvent e) { 49 System.exit(0); 50 } 51 }); 52 ventana.setResizable(false); 53 createBufferStrategy(2); 54 strategy = getBufferStrategy(); 55 requestFocus();
56 addKeyListener(this);
57 } 58 59 public void initWorld() { 60 actors = new ArrayList(); 61 for (int i = 0; i < 10; i++){ 62 Monster m = new Monster(this); 63 m.setX( (int)(Math.random()*Stage.WIDTH) ); 64 m.setY( i*20 ); 65 m.setVx( (int)(Math.random()*20-10) ); 66 67 actors.add(m); 68 } 69 70 player = new Player(this); 71 player.setX(Stage.WIDTH/2); 72 player.setY(Stage.HEIGHT - 2*player.getHeight()); 73 } 74 75 76 77 public void updateWorld() { 78 for (int i = 0; i < actors.size(); i++) { 79 Actor m = (Actor)actors.get(i); 80 m.act(); 81 } 82 player.act(); 83 } 84 85 public void paintWorld() { 86 Graphics2D g = (Graphics2D)strategy.getDrawGraphics(); 87 g.setColor(Color.black); 88 g.fillRect(0,0,getWidth(),getHeight()); 89 for (int i = 0; i < actors.size(); i++) { 90 Actor m = (Actor)actors.get(i); 91 m.paint(g); 92 } 93 player.paint(g); 94 95 g.setColor(Color.white); 96 if (usedTime > 0) 97 g.drawString(String.valueOf(1000/usedTime)+" fps",0,Stage.HEIGHT-50); 98 else 99 g.drawString("--- fps",0,Stage.HEIGHT-50); 100 strategy.show(); 101 } 102 103 public SpriteCache getSpriteCache() { 104 return spriteCache;
105 } 106 107 public void keyPressed(KeyEvent e) { 108 player.keyPressed(e); 109 } 110 111 public void keyReleased(KeyEvent e) { 112 player.keyReleased(e);
113 } 114 public void keyTyped(KeyEvent e) {} 115 116 public void game() { 117 usedTime=1000; 118 initWorld(); 119 while (isVisible()) { 120 long startTime = System.currentTimeMillis(); 121 updateWorld(); 122 paintWorld(); 123 usedTime = System.currentTimeMillis()-startTime; 124 try { 125 Thread.sleep(SPEED); 126 } catch (InterruptedException e) {} 127 } 128 } 129 130 public static void main(String[] args) { 131 Invaders inv = new Invaders(); 132 inv.game(); 133 } 134 } 135

And the player class becomes:


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 version17;
10    
11    import java.awt.event.KeyEvent;
12    
13    public class Player extends Actor {
14      protected static final int PLAYER_SPEED = 4;
15      protected int vx;
16      protected int vy;
17      private boolean up,down,left,right;
18        
19      
20      public Player(Stage stage) {
21        super(stage);
22        setSpriteNames( new String[] {"nave.gif"});
23      }
24      
25      public void act() {
26        super.act();
27        x+=vx;
28        y+=vy;
29        if (x < 0 || x > Stage.WIDTH)
30          vx = -vx;
31        if (y < 0 || y > Stage.HEIGHT)
32          vy = -vy;
33      }
34    
35      public int getVx() { return vx; }
36      public void setVx(int i) {vx = i; }
37      public int getVy() { return vy; }
38      public void setVy(int i) {vy = i; }
39      
40      
41 protected void updateSpeed() { 42 vx=0;vy=0; 43 if (down) vy = PLAYER_SPEED; 44 if (up) vy = -PLAYER_SPEED; 45 if (left) vx = -PLAYER_SPEED; 46 if (right) vx = PLAYER_SPEED; 47 } 48 49 public void keyReleased(KeyEvent e) { 50 switch (e.getKeyCode()) { 51 case KeyEvent.VK_DOWN : down = false;break; 52 case KeyEvent.VK_UP : up = false; break; 53 case KeyEvent.VK_LEFT : left = false; break; 54 case KeyEvent.VK_RIGHT : right = false;break; 55 } 56 updateSpeed(); 57 } 58 59 public void keyPressed(KeyEvent e) { 60 switch (e.getKeyCode()) { 61 case KeyEvent.VK_UP : up = true; break; 62 case KeyEvent.VK_LEFT : left = true; break; 63 case KeyEvent.VK_RIGHT : right = true; break; 64 case KeyEvent.VK_DOWN : down = true;break; 65 } 66 updateSpeed(); 67 }
68 69 } 70

We've defined also a constant called PLAYER_SPEED, so that the cursor keys only change the direction of the player, but not the speed.



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 Invaders.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 - The Player Current Page - 17 - Controlling the player   Next Page - Shots
  Return to the index of free Java tutorials  

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