Planetalia - Java Training

Training and Consulting

Home

Tutorial - Writing a Space Invaders game in Java

  Previous Page - Controlled movement Current Page - 10 - Flicker   Next Page - JDK Support for Double Buffering
  Return to the index of free Java tutorials  

Flicker

(c) Alexander Hristov

Unless we have an extremely fast computer and a monitor with an extremely high refresh frequency, probably by now we can clearly see the problem with our approach regarding the treatment of the screen: The dreaded flicker. Flickering takes place because for some instants the eye is seeing the "just cleaned" screen, upon which we have still not painted any actors.

Solving this problem involves a standard approach called double buffering. This technique consists in having an image in memory with the same characteristics (height, width, color depth, etc..) as the screen, and performing all the drawing in this in-memory, off-screen image. Once everything is ready, we just copy this in-memory image to the screen. In this way, the user never really sees the intermediate steps that take place when we are redrawing the world. The off-screen image by the way is usually called image buffer


1     package version10;
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.Dimension;
14    import java.awt.Graphics;
15    import java.awt.event.WindowAdapter;
16    import java.awt.event.WindowEvent;
17    import java.awt.image.BufferedImage;
18    import java.net.URL;
19    import java.util.HashMap;
20    
21    import javax.imageio.ImageIO;
22    import javax.swing.JFrame;
23    import javax.swing.JPanel;
24    
25    public class Invaders extends Canvas {
26      public static final int WIDTH = 640;
27      public static final int HEIGHT = 480;
28      public static final int SPEED = 10;
29      
30      public HashMap sprites;
31      public int posX,posY,vX;
32 public BufferedImage buffer;
33 34 public Invaders() { 35 sprites = new HashMap(); 36 posX = WIDTH/2; 37 posY = HEIGHT/2; 38 vX = 2;
39 buffer = new BufferedImage(WIDTH,HEIGHT, BufferedImage.TYPE_INT_RGB);
40 41 JFrame ventana = new JFrame("Invaders"); 42 ventana.createBufferStrategy(2); 43 44 45 JPanel panel = (JPanel)ventana.getContentPane(); 46 setBounds(0,0,WIDTH,HEIGHT); 47 panel.setPreferredSize(new Dimension(WIDTH,HEIGHT)); 48 panel.setLayout(null); 49 panel.add(this); 50 ventana.setBounds(0,0,WIDTH,HEIGHT); 51 ventana.setVisible(true); 52 ventana.addWindowListener( new WindowAdapter() { 53 public void windowClosing(WindowEvent e) { 54 System.exit(0); 55 } 56 }); 57 ventana.setIgnoreRepaint(true); 58 ventana.setResizable(false); 59 } 60 61 public BufferedImage loadImage(String nombre) { 62 URL url=null; 63 try { 64 url = getClass().getClassLoader().getResource(nombre); 65 return ImageIO.read(url); 66 } catch (Exception e) { 67 System.out.println("No se pudo cargar la imagen " + nombre +" de "+url); 68 System.out.println("El error fue : "+e.getClass().getName()+" "+e.getMessage()); 69 System.exit(0); 70 return null; 71 } 72 } 73 74 public BufferedImage getSprite(String nombre) { 75 BufferedImage img = (BufferedImage)sprites.get(nombre); 76 if (img == null) { 77 img = loadImage("res/"+nombre); 78 sprites.put(nombre,img); 79 }
80 return img; 81 } 82 83 public void paintWorld() { 84 Graphics g = buffer.getGraphics(); 85 g.setColor(getBackground()); 86 g.fillRect(0,0,getWidth(),getHeight()); 87 g.drawImage(getSprite("bicho.gif"), posX, posY,this); 88 } 89 90 91 public void paint(Graphics g) {
92 g.drawImage(buffer,0,0,this); 93 } 94 95 public void updateWorld() { 96 posX += vX; 97 if (posX < 0 || posX > WIDTH) vX = -vX; 98 } 99 100 public void game() { 101 while (isVisible()) { 102 updateWorld(); 103 paintWorld(); 104 paint(getGraphics()); 105 try { 106 Thread.sleep(SPEED); 107 } catch (InterruptedException e) {} 108 } 109 } 110 111 public static void main(String[] args) { 112 Invaders inv = new Invaders(); 113 inv.game(); 114 } 115 } 116


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


Full list of Java source files for this step

Invaders.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 - Controlled movement Current Page - 10 - Flicker   Next Page - JDK Support for Double Buffering
  Return to the index of free Java tutorials  

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