Cursos y Másters | ||
| Inicio Profesores Aulas Testimonios Cursos Masters Tecnologías Cursos Gratuitos Galería de Proyectos Solicitar Información |
| Página Anterior - Controlando el jugador | Página Actual - 18 - Disparos | Página Siguiente - Más disparos - Bombas de fragmentación |
| Índice de cursos Java gratuitos |
DisparosHa llegado el momento de añadir algo de violencia a nuestro pacífico juego - la posibilidad de que el jugador dispare. Nos conformaremos inicialmente con poder disparar y de momento dejaremos el efecto que los disparos producen sobre el entorno (en particular los monstruos) para más adelante. Nuestros disparos tendrán las siguientes premisas:
Desde el punto de vista del programa, los disparos son simplemente actores. Lo novedoso es que los disparos aparecen y desaparecen sobre la marcha y dependiendo de circunstancias que el bucle principal del programa no controla. Por ejemplo, cuando se pulsa la barra espaciadora, aparece un disparo. Este actor debe ser añadido a la lista, pero la gestión de las teclas la hace la clase Player, y no sería correcto que esta clase "metiera la mano" dentro de la lista de actores, ya que esta lista es una estructura de datos propia de la clase Invaders. Una solución es dotar al escenario de métodos que permitan añadir y quitar actores sobre la marcha. Con esta idea, la interfaz Stage quedaría de la siguiente forma:
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 version18; 10 11 import java.awt.image.ImageObserver; 12 13 public interface Stage extends ImageObserver { 14 public static final int WIDTH=640; 15 public static final int HEIGHT=480; 16 public static final int SPEED=10; 17 public SpriteCache getSpriteCache(); Ahora bien, hay un problema importante que no es obvio a primera vista : ¿quién borra los actores? Lo primero que se nos podría ocurrir es añadir un método removeActor(...) igual que el otro. Pero surge un problema y es que es posible que el borrado de un actor se haga como respuesta a la pulsación de una tecla, o bien como consecuencia de un método act() de otro actor. En el primer caso, el borrado se estaría produciendo desde un hilo distinto al principal (nada bueno ya que estaríamos manipulando una estructura de datos desde un hilo, mientras que desde el principal tal vez la estemos recorriendo). En el segundo caso, estaríamos en una situación similar - podría producirse un desajuste en el bucle y que el método act() de algún actor no fuese llamado Para evitar ambas situaciones, en lugar de borrar un actor directamente definiremos una marca que indique que un actor determinado está "marcado para ser borrado". Posteriormente será el bucle principal el único que comprobará dicha marca y eliminará el actor si procede: Esto requiere una modificación a la clase Actor de la siguiente forma:
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 version18; 10 11 import java.awt.Graphics2D; 12 import java.awt.image.BufferedImage; 13 14 public class Actor { 15 protected int x,y; 16 protected int width, height; 17 protected String[] spriteNames; 18 protected int currentFrame; 19 protected int frameSpeed; 20 protected int t; 21 protected Stage stage; 22 protected SpriteCache spriteCache; 24 25 public Actor(Stage stage) { 26 this.stage = stage; 27 spriteCache = stage.getSpriteCache(); 28 currentFrame = 0; 29 frameSpeed = 1; 30 t=0; 31 } 32 Los métodos updateWorld() y addActor() de la clase Invaders.java quedarían de la siguiente forma:
. . .
75 public void addActor(Actor a) {
76 actors.add(a);
77 }
78
79 public void updateWorld() {
80 int i = 0;
81 while (i < actors.size()) {
82 Actor m = (Actor)actors.get(i);
83 if (m.isMarkedForRemoval()) {
84 actors.remove(i);
85 } else {
86 m.act();
87 i++;
88 }
89 }
90 player.act();
91 }
. . .
Una vez que hemos resuelto los problemas de adición y eliminación de actores, podemos comenzar a añadir la gestión de los disparos. Para el disparo utilizaremos el siguiente gráfico, llamado "disparo.gif":
Los disparos, al tener su propio comportamiento, van a estar representados por una nueva clase llamada Bullet:
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 version18; 10 11 12 public class Bullet extends Actor { 13 protected static final int BULLET_SPEED=10; 14 15 public Bullet(Stage stage) { 16 super(stage); 17 setSpriteNames( new String[] {"misil.gif"}); 18 } 19 20 public void act() { 21 super.act(); 22 y-=BULLET_SPEED; 23 if (y < 0) 24 remove(); 25 } 26 } 27 Se puede ver que el metodo act() borra automáticamente el disparo cuando detecta que ha salido por la parte superior de la pantalla Por último, queda añadir la gestión de la tecla de disparo a la clase Player:
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 version18; 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; 66 } 67 updateSpeed(); 68 } 69
|
||||||||||||||||||||||||||||||||
¿Quieres ser notificado cuando salan nuevos tutoriales y cursos?. Pulsa aquí
| Actor.java | Bullet.java | Invaders.java | Monster.java |
| Player.java | SpriteCache.java | Stage.java |
| Página Anterior - Controlando el jugador | Página Actual - 18 - Disparos | Página Siguiente - Más disparos - Bombas de fragmentación |
| Índice de cursos Java gratuitos |
(c) 2004 Planetalia S.L. Todos los derechos reservados. Prohibida su reproducción