Planetalia - Cursos

Cursos y Másters

Inicio    Profesores    Aulas    Testimonios    Cursos    Masters    Tecnologías    Cursos Gratuitos    Galería de Proyectos    Solicitar Información   

Curso - Programación de un Space Invaders en Java

  Página Anterior - La venganza de los monstruos Página Actual - 25 - Fondo con scroll   Página Siguiente - Reaparición de monstruos
  Índice de cursos Java gratuitos  

Fondo con scroll

(c) Alexander Hristov

Muchos juegos ofrecen un aspecto visual muy efectista gracias a un fondo con scroll sobre el qeu se desarrolla la acción. Este efecto es muy fácil de conseguir si simplemente en lugar de borrar la pantalla con un color sólido la rellenamos con una textura. El scroll se consigue modificando el rectángulo que actúa como ancla de la textura. Para entender el proceso, imaginemos que tenemos la siguiente imagen que utilizaremos como textura del fondo:

Si rellenamos toda la pantalla con esta textura utilizando un rectángulo ancla de (0,0,256,256), obtenemos lo siguiente :

Ahora si utilizamos un rectángulo ancla de (0,20,256,256), es decir, si aumentamos la coordenada y del rectángulo en 20 unidades, obtenemos esto otro:

El efecto es como si todo el decorado se hubiese desplazado hacia abajo 20 unidades. Precisamente esta es la forma en que conseguiremos nuestro efecto para el fondo. Por supuesto, dado que queremos un desplazamiento suave, aumentaremos la coordenada en un pixel cada vez. También utilizaremos una imagen más apropiada para un fondo, como por ejemplo la siguiente, llamada "oceano.gif":

La única clase que cambiará en este paso es la clase Invaders en la que efectuamos las siguientes modificaciones:


1     package version25;
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.Font;
16    import java.awt.Graphics2D;
17    import java.awt.Rectangle;
18    import java.awt.TexturePaint;
19    import java.awt.event.KeyEvent;
20    import java.awt.event.KeyListener;
21    import java.awt.event.WindowAdapter;
22    import java.awt.event.WindowEvent;
23    import java.awt.image.BufferStrategy;
24    import java.awt.image.BufferedImage;
25    import java.util.ArrayList;
26    
27    import javax.swing.JFrame;
28    import javax.swing.JPanel;
29    
30    public class Invaders extends Canvas implements Stage, KeyListener {
31      
32      private BufferStrategy strategy;
33      private long usedTime;
34      
35      private SpriteCache spriteCache;
36      private ArrayList actors; 
37      private Player player;
38 private BufferedImage ocean; 39 private int t;
40 41 private boolean gameEnded=false; 42 43 public Invaders() { 44 spriteCache = new SpriteCache(); 45 46 47 JFrame ventana = new JFrame("Invaders"); 48 JPanel panel = (JPanel)ventana.getContentPane(); 49 setBounds(0,0,Stage.WIDTH,Stage.HEIGHT); 50 panel.setPreferredSize(new Dimension(Stage.WIDTH,Stage.HEIGHT)); 51 panel.setLayout(null); 52 panel.add(this); 53 ventana.setBounds(0,0,Stage.WIDTH,Stage.HEIGHT); 54 ventana.setVisible(true); 55 ventana.addWindowListener( new WindowAdapter() { 56 public void windowClosing(WindowEvent e) { 57 System.exit(0); 58 } 59 }); 60 ventana.setResizable(false); 61 createBufferStrategy(2); 62 strategy = getBufferStrategy(); 63 requestFocus(); 64 addKeyListener(this); 65 } 66 67 public void gameOver() { 68 gameEnded = true; 69 } 70 71 public void initWorld() { 72 actors = new ArrayList(); 73 for (int i = 0; i < 10; i++){ 74 Monster m = new Monster(this); 75 m.setX( (int)(Math.random()*Stage.WIDTH) ); 76 m.setY( i*20 ); 77 m.setVx( (int)(Math.random()*20-10) ); 78 79 actors.add(m); 80 } 81 82 player = new Player(this); 83 player.setX(Stage.WIDTH/2); 84 player.setY(Stage.PLAY_HEIGHT - 2*player.getHeight()); 85 } 86 87 public void addActor(Actor a) { 88 actors.add(a); 89 } 90 91 public Player getPlayer() { 92 return player; 93 } 94 95 public void updateWorld() { 96 int i = 0; 97 while (i < actors.size()) { 98 Actor m = (Actor)actors.get(i); 99 if (m.isMarkedForRemoval()) { 100 actors.remove(i); 101 } else { 102 m.act(); 103 i++; 104 } 105 } 106 player.act(); 107 } 108 109 public void checkCollisions() { 110 Rectangle playerBounds = player.getBounds(); 111 for (int i = 0; i < actors.size(); i++) { 112 Actor a1 = (Actor)actors.get(i); 113 Rectangle r1 = a1.getBounds(); 114 if (r1.intersects(playerBounds)) { 115 player.collision(a1); 116 a1.collision(player); 117 } 118 for (int j = i+1; j < actors.size(); j++) { 119 Actor a2 = (Actor)actors.get(j); 120 Rectangle r2 = a2.getBounds(); 121 if (r1.intersects(r2)) { 122 a1.collision(a2); 123 a2.collision(a1); 124 } 125 } 126 } 127 } 128 129 public void paintShields(Graphics2D g) { 130 g.setPaint(Color.red); 131 g.fillRect(280,Stage.PLAY_HEIGHT,Player.MAX_SHIELDS,30); 132 g.setPaint(Color.blue); 133 g.fillRect(280+Player.MAX_SHIELDS-player.getShields(),Stage.PLAY_HEIGHT,player.getShields(),30); 134 g.setFont(new Font("Arial",Font.BOLD,20)); 135 g.setPaint(Color.green); 136 g.drawString("Shields",170,Stage.PLAY_HEIGHT+20); 137 138 } 139 140 public void paintScore(Graphics2D g) { 141 g.setFont(new Font("Arial",Font.BOLD,20)); 142 g.setPaint(Color.green); 143 g.drawString("Score:",20,Stage.PLAY_HEIGHT + 20); 144 g.setPaint(Color.red); 145 g.drawString(player.getScore()+"",100,Stage.PLAY_HEIGHT + 20); 146 } 147 148 public void paintAmmo(Graphics2D g) { 149 int xBase = 280+Player.MAX_SHIELDS+10; 150 for (int i = 0; i < player.getClusterBombs();i++) { 151 BufferedImage bomb = spriteCache.getSprite("bombUL.gif"); 152 g.drawImage( bomb ,xBase+i*bomb.getWidth(),Stage.PLAY_HEIGHT,this); 153 } 154 } 155 156 public void paintfps(Graphics2D g) { 157 g.setFont( new Font("Arial",Font.BOLD,12)); 158 g.setColor(Color.white); 159 if (usedTime > 0) 160 g.drawString(String.valueOf(1000/usedTime)+" fps",Stage.WIDTH-50,Stage.PLAY_HEIGHT); 161 else 162 g.drawString("--- fps",Stage.WIDTH-50,Stage.PLAY_HEIGHT); 163 } 164 165 166 public void paintStatus(Graphics2D g) { 167 paintScore(g); 168 paintShields(g); 169 paintAmmo(g); 170 paintfps(g); 171 } 172 173 public void paintWorld() { 174 Graphics2D g = (Graphics2D)strategy.getDrawGraphics();
175 ocean = spriteCache.getSprite("oceano.gif"); 176 g.setPaint(new TexturePaint(ocean, new Rectangle(0,t,ocean.getWidth(),ocean.getHeight()))); 177 g.fillRect(0,0,getWidth(),getHeight());
178 for (int i = 0; i < actors.size(); i++) { 179 Actor m = (Actor)actors.get(i); 180 m.paint(g); 181 } 182 player.paint(g); 183 184 185 paintStatus(g); 186 strategy.show(); 187 } 188 189 public void paintGameOver() { 190 Graphics2D g = (Graphics2D)strategy.getDrawGraphics(); 191 g.setColor(Color.white); 192 g.setFont(new Font("Arial",Font.BOLD,20)); 193 g.drawString("GAME OVER",Stage.WIDTH/2-50,Stage.HEIGHT/2); 194 strategy.show(); 195 } 196 197 public SpriteCache getSpriteCache() { 198 return spriteCache; 199 } 200 201 public void keyPressed(KeyEvent e) { 202 player.keyPressed(e); 203 } 204 205 public void keyReleased(KeyEvent e) { 206 player.keyReleased(e); 207 } 208 public void keyTyped(KeyEvent e) {} 209 210 public void game() { 211 usedTime=1000;
212 t = 0;
213 initWorld(); 214 while (isVisible() && !gameEnded) {
215 t++;
216 long startTime = System.currentTimeMillis(); 217 updateWorld(); 218 checkCollisions(); 219 paintWorld(); 220 usedTime = System.currentTimeMillis()-startTime; 221 try { 222 Thread.sleep(SPEED); 223 } catch (InterruptedException e) {} 224 } 225 paintGameOver(); 226 } 227 228 public static void main(String[] args) { 229 Invaders inv = new Invaders(); 230 inv.game(); 231 } 232 } 233

El efecto que conseguimos es el siguiente:



¿Quieres ser notificado cuando salan nuevos tutoriales y cursos?. Pulsa aquí


Lista de archivos Java del programa en este paso

Actor.java Bomb.java Bullet.java Invaders.java
Laser.java Monster.java Player.java SpriteCache.java
Stage.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 test.gif
Thumbs.db      

  Página Anterior - La venganza de los monstruos Página Actual - 25 - Fondo con scroll   Página Siguiente - Reaparición de monstruos
  Índice de cursos Java gratuitos  

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