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 - Fotogramas Página Actual - 15 - Fotogramas - II   Página Siguiente - El Jugador
  Índice de cursos Java gratuitos  

Fotogramas - II

(c) Alexander Hristov

Si tenemos un ordenador suficientemente rápido, los fotogramas del programa anterior avanzan a una velocidad excesiva y apenas da tiempo a verlos como fotogramas diferenciados. Sin embargo, la frecuencia con la que se llama al método act() es algo que es general para todo el juego y no podemos variarlo para cada caso individual

La solución la tomamos prestada de la electrónica mediante lo que se llama una base de tiempos. El bucle principal duerme durante un tiempo que queda determinado por el máximo común divisor de los tiempos del resto de objetos. Por ejemplo imaginemos que estamos haciendo un videojuego en el cual los monstruos se actúan a la velocidad de una vez por segundo, mientras que el jugador actúa a una velocidad de 2 veces por segundo (o dicho de otra forma, queremos que tenga un "turno" para hacer cosas dos veces por segundo, o una vez cada medio segundo). Tenemos también un volcán que hace erupción cada 10 segundos. El máximo común divisor entre 1, 0.5 y 10 es 0.5. Este MCD recibe el nombre de unidad de tiempo o base de tiempos y es el tiempo que dormirá en general el bucle principal.

Dentro del bucle principal, cada vez que salgamos del Thread.sleep, se incrementa un contador secuencial que hace las veces de "instante del tiempo". Cuando este contador sea divisible por la cantidad apropiada, entonces es cuando se realiza la actualización del objeto en cuestión. Esta "cantidad apropiada" es el resultado de dividir el intervalo en segundos entres dos movimientos sucesivos del objeto por el MCD calculado anteriormente. Como en nuestro ejemplo la unidad de tiempo es de 0.5 segundos, el esquema sería:

  • Jugador - Se actualiza siempre ( 0.5 / 0.5 = 1 )
  • Monstruo - Se mueve cada 2 unidades de tiempo, por lo tanto se actualiza cada vez que el contador sea divisible por 2.
  • Volcán - Entra en erupción cada 10 segundos, o cada 20 unidades de tiempo, por lo que se actualiza cada vez que el contador sea divisible por 20.

El mismo criterio podemos aplicar a los fotogramas : Podemos mantener dentro de la clase Actor un contador de tiempos y actualizar el fotograma sólo cuando este contador sea divisible por una cantidad que llamaremos "velocidad de los fotogramas". Con este razonamiento, la clase "Actor" quedaría como sigue:


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 version15;
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; 23 24 public Actor(Stage stage) { 25 this.stage = stage; 26 spriteCache = stage.getSpriteCache(); 27 currentFrame = 0; 28 frameSpeed = 1; 29 t=0; 30 } 31 32 public void paint(Graphics2D g){ 33 g.drawImage( spriteCache.getSprite(spriteNames[currentFrame]), x,y, stage ); 34 } 35 36 public int getX() { return x; } 37 public void setX(int i) { x = i; } 38 39 public int getY() { return y; } 40 public void setY(int i) { y = i; } 41 42 public int getFrameSpeed() {return frameSpeed; } 43 public void setFrameSpeed(int i) {frameSpeed = i; } 44 45 46 public void setSpriteNames(String[] names) { 47 spriteNames = names; 48 height = 0; 49 width = 0; 50 for (int i = 0; i < names.length; i++ ) { 51 BufferedImage image = spriteCache.getSprite(spriteNames[i]); 52 height = Math.max(height,image.getHeight()); 53 width = Math.max(width,image.getWidth()); 54 } 55 } 56 57 public int getHeight() { return height; } 58 public int getWidth() { return width; } 59 public void setHeight(int i) {height = i; } 60 public void setWidth(int i) { width = i; } 61 62 public void act() {
63 t++; 64 if (t % frameSpeed == 0){ 65 t=0; 66 currentFrame = (currentFrame + 1) % spriteNames.length; 67 }
68 } 69 } 70

Los descendientes de esta clase tendrían que preocuparse cada uno de establecer su propia velocidad de fotogramas. Por ejemplo la clase Monster quedaría así:


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 version15;
10    
11    public class Monster extends Actor {
12      protected int vx;
13      
14      public Monster(Stage stage) {
15        super(stage);
16        setSpriteNames( new String[] {"bicho0.gif","bicho1.gif"});
17 setFrameSpeed(35);
18 } 19 20 public void act() { 21 super.act(); 22 x+=vx; 23 if (x < 0 || x > Stage.WIDTH) 24 vx = -vx; 25 } 26 27 public int getVx() { return vx; } 28 public void setVx(int i) {vx = i; }} 29

Haber declarado la variable t como protegida permitirá a los descendientes utilizar la misma variable para hacer otros cálculos basados en la base de tiempos común (por ejemplo, determinar cuando hay que disparar, cuando debe "mutar" un monstruo, etc...



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


Lista de archivos Java del programa en este paso

Actor.java Invaders.java Monster.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 - Fotogramas Página Actual - 15 - Fotogramas - II   Página Siguiente - El Jugador
  Índice de cursos Java gratuitos  

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