Curso - Programación de un Space Invaders en Java

  Página Anterior - Controlando el caos Página Actual - 10 - Más lento que el ojo   Página Siguiente - Doble Búfer automático
  Índice del curso  

Más lento que el ojo

(c) Alexander Hristov

Salvo que tengamos un ordenaro excepcionalmente rápido, nos habremos percatado que el programa anterior tiene un defecto extremadamente molesto y es un parpadeo en el bicho. El parpadeo ocurre porque durante unos instantes el ojo está viendo la pantalla recién borrada en la que todavía no se ha pintado ningún bicho. Si el ordenador que tenemos es muy rápido y no podemos apreciarlo, basta en general con aumentar el tamaño de la ventana o utilizar gráficos más grandes para que el efecto pase a ser apreciable.

Para resolver esta situación utilizaremos una técnica llamada double buffering. Esta técnica consiste en tener una imagen en memoria del mismo tamaño que el escenario en la cual se hacen todas las operaciones gráficas. Una vez que el escenario ha sido pintado "fuera de la pantalla" (off-screen), esa imagen en memoria es volcada encima de la ventana. A esta imagen en memoria se la suele llamar 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


Lista de archivos Java del programa en este paso

Invaders.java      

Lista de recursos

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 Thumbs.db

  Página Anterior - Controlando el caos Página Actual - 10 - Más lento que el ojo   Página Siguiente - Doble Búfer automático
  Índice del curso  

(c) 2004 Planetalia S.L. Todos los derechos reservados. Prohibida su reproducción