Download Estudio y Análisis de algoritmos para la realización de

Document related concepts
no text concepts found
Transcript
!
&
" #
'
$%
$%
(
) * +,-./0
*
1
2 3
2 44- * 445
"There is no way to happiness. Happiness is the way.
There is no way to peace. Peace is the way.
There is no way to enlightenment. Enlightenment is the way."
...Thich Nhat Hanh-Buddha
Rafael Campillo Lorenzo.
TCM-SPC (2005-2006)
“Cavaleiro dos Céus”
Jogo de computador2D
El proyecto “O cavaleiro dos céus - Jogo de computador 2D”, tiene una parte práctica
consistente en la realización de un juego de computador en 2 dimensiones, y una parte de
investigación teórica en la que se estudian distintas técnicas y algoritmos que conduzcan a
la realización de un juego 2D de computador.
2
Rafael Campillo Lorenzo.
“Cavaleiro dos Céus”
TCM-SPC (2005-2006)
6
Jogo de computador2D
7&
Quería agradecer toda su inestimable ayuda y apoyo en la realización del proyecto al
orientador de éste: el Profesor Alexandre Carvalho, y a la profesora de la disciplina Renata
Barbosa.
A Luis Peralta [Peralta2005] por haberme cedido el software de creación propia
WW2plane, para la generación de aviones de la segunda guerra mundial.
También quería agradecer al ISMAI y a todos los responsables del curso de Tecnología da
Comunicação Multimedia la oportunidad que se me ha brindado de estudiar este año
académico aquí en Maia.
A todos… ¡GRACIAS!
Dedicado a mis padres y hermanos…
3
Rafael Campillo Lorenzo.
TCM-SPC (2005-2006)
“Cavaleiro dos Céus”
Jogo de computador2D
7
Sumario................................................................................................................................... 2
Agradecimientos..................................................................................................................... 3
Índice de ilustraciones ............................................................................................................ 8
1. Introducción........................................................................................................................ 9
1.1. Contexto ...................................................................................................................... 9
1.1.1 Proceso previo ....................................................................................................... 9
1.1.2. Motivación......................................................................................................... 10
1.2 Finalidad y Objetivos ................................................................................................. 11
1.3. Estructura del documento .......................................................................................... 12
2. Estado de conocimiento.................................................................................................... 13
2.1. Historia de los videojuegos Arcade ........................................................................... 13
2.2. Presentación del trabajo............................................................................................. 15
2.3. Conceptos .................................................................................................................. 15
2.3.1. Sprites ................................................................................................................. 15
2.3.2. Coordenadas polares. Distancia entre dos puntos y cambios de coordenadas
polares – cartesianas ..................................................................................................... 16
2.3.3. Imágenes. Formatos de fichero........................................................................... 18
2.4. Técnicas de juegos arcade ......................................................................................... 19
2.4.1. Active Rendering (Rendering activo)................................................................. 19
2.4.2. Carga tardía......................................................................................................... 20
2.4.3. Doble Buffering.................................................................................................. 21
2.4.4. Page flipping....................................................................................................... 22
2.4.5. Animación: Fotogramas o Frames...................................................................... 23
2.4.6. Transformaciones Afines.................................................................................... 25
2.4.7. Gestión de eventos.............................................................................................. 25
2.4.8. Scroll................................................................................................................... 26
2.4.9. Detección de colisiones ...................................................................................... 27
2.4.10. Patrones de movimiento. Algoritmo Estándar.................................................. 30
4
Rafael Campillo Lorenzo.
TCM-SPC (2005-2006)
“Cavaleiro dos Céus”
Jogo de computador2D
2.4.11. Persecución y Evasión básicas ......................................................................... 32
2.4.12. Inteligencia Artificial en juegos ....................................................................... 34
3. Descripción....................................................................................................................... 36
3.1. Descripción General .................................................................................................. 36
3.2. Descripción por Bloques ........................................................................................... 38
3.3. Descripción de las Clases .......................................................................................... 39
3.3.1. Jerarquía de Clases ............................................................................................. 39
3.3.2. Class Jogo2D ...................................................................................................... 40
3.3.3. Clase GraficosCache........................................................................................... 41
3.3.4. Clase SonidoCache ............................................................................................. 42
3.3.5. Clase RecursosCache.......................................................................................... 42
3.3.6. Clase Escenario................................................................................................... 42
3.3.7. Clase Sprite......................................................................................................... 43
3.3.8. Clase Enemigo.................................................................................................... 44
3.3.9. Clase Jugador...................................................................................................... 45
3.3.10. Clase Tiros........................................................................................................ 45
3.3.11. Clase Bomba..................................................................................................... 45
3.3.12. Clase TirosEnemigo ......................................................................................... 46
3.3.13. Clase PuntosExtra............................................................................................. 46
3.3.14. Clase Fondos .................................................................................................... 46
3.3.15. Clase Scroller.................................................................................................... 46
3.3.16. Clase Comportamiento ..................................................................................... 47
4. Implementación ................................................................................................................ 49
4.1. Etapas más importantes seguidas para el desarrollo del juego.................................. 49
4.2. Herramientas.............................................................................................................. 51
4.2.1. Java 1.4.2_10 SDK ............................................................................................. 52
4.2.2. Abstracción......................................................................................................... 54
4.2.3. Encapsulación..................................................................................................... 54
4.2.4. Herencia.............................................................................................................. 55
5
Rafael Campillo Lorenzo.
TCM-SPC (2005-2006)
“Cavaleiro dos Céus”
Jogo de computador2D
4.2.5. Polimorfismo ...................................................................................................... 55
4.2.6. Eclipse 3.1 ......................................................................................................... 56
4.3 Técnicas usadas en la implementación del juego ....................................................... 57
4.3.1. Gestión de eventos.............................................................................................. 57
4.3.2. Fotogramas ......................................................................................................... 58
4.3.3. Transformaciones Afines.................................................................................... 59
4.3.4. Carga de imágenes.............................................................................................. 60
4.3.5. Imágenes Compatibles........................................................................................ 61
4.3.6. Doble Buffering.................................................................................................. 62
4.3.7. Colisiones ........................................................................................................... 63
4.4. Librerías..................................................................................................................... 64
4.4.1. javax.swing.JFrame ............................................................................................ 65
4.4.2 java.*.BufferedImage .......................................................................................... 65
4.4.3. java.*.BufferStrategy.......................................................................................... 65
4.4.4. java.util.HashMap............................................................................................... 66
4.4.5. java.awt.event.KeyEvent .................................................................................... 66
4.4.6. java.awt.Graphics2D .......................................................................................... 66
5. Desarrollo de la parte Gráfica del juego........................................................................... 68
5.1. Proceso de creación de los sprites ............................................................................. 68
5.2. Explosiones................................................................................................................ 71
5.3. Creación de los escenarios......................................................................................... 71
5.4. Creación de la pantalla de presentación de las fases ................................................. 72
6. Resultados......................................................................................................................... 73
7. Conclusiones..................................................................................................................... 76
8. Bibliografía....................................................................................................................... 79
9. Índice remisivo ................................................................................................................. 81
10. Anexos ............................................................................................................................ 82
10.1. Anexo I: Manual de Usuario ................................................................................... 82
10.1.1. Instalación......................................................................................................... 82
6
Rafael Campillo Lorenzo.
TCM-SPC (2005-2006)
“Cavaleiro dos Céus”
Jogo de computador2D
10.1.2. Comandos para el manejo del juego................................................................. 83
10.1.3. Reglas del juego ............................................................................................... 84
10.2. Anexo II: Imágenes y texturas del juego. ................................................................ 87
7
Rafael Campillo Lorenzo.
“Cavaleiro dos Céus”
TCM-SPC (2005-2006)
87
Jogo de computador2D
&
7
Figura 1 – Distancia entre dos puntos .................................................................................. 17
Figura 2 - Coordenadas polares de un punto ........................................................................ 17
Figura 3 - Scroll basado en baldosas descomponiendo un mapa de bits en pequeños objetos
gráficos, creando un mapa del gráfico.......................................................................... 27
Figura 4 - Posibles cambios de estado de un objeto que se desplaza por la pantalla .......... 35
Figura 5 - Jerarquía de Clases............................................................................................... 39
Figura 6 – Ejemplo compiladores para distintas plataformas y de la JVM......................... 52
Figura 7- Intersección de los rectángulos de dos sprites. ..................................................... 63
Figura 8 - Logotipo de WW2plane....................................................................................... 68
Figura 9 - Macros creadas para Photoshop CS2.................................................................. 69
Figura 10 - Secuencia sprites de un avión japonés............................................................... 70
Figura 11 - Secuencia de sprites de un avión alemán........................................................... 70
Figura 12 - Secuencia de sprites de puntosExtra.................................................................. 70
Figura 13 - Secuencia de sprites de una explosión............................................................... 71
8
Rafael Campillo Lorenzo.
“Cavaleiro dos Céus”
TCM-SPC (2005-2006)
,9 7 &
Jogo de computador2D
:7
El proyecto consiste en analizar y estudiar las técnicas y algoritmos que conduzcan a la
realización de un Juego 2D de computador.
Como parte práctica a complementar la realización del trabajo de investigación teórico, se
ha desarrollado un juego de computador en dos dimensiones tipo arcade con scroll,
recurriendo a la tecnología de desarrollo orientada a objetos y computación gráfica 2D. El
lenguaje de programación que se consideró más adecuado para el desarrollo de este juego
es el lenguaje Java.
Algunas de las técnicas de estudio para la realización de la parte práctica de la monografía
son:
La translación de imágenes en la pantalla.
La visualización de los sprites y su animación.
La gestión de eventos.
,9,9
1
1.1.1 Proceso previo
Una de las partes más complicadas y por ello más importantes de todas fue la elección del
proyecto a realizar. Pero con la inestimable ayuda del orientador, el profesor Alexandre
Carvalho, se pudo escoger el proyecto a realizar entre un abanico de posibilidades muy
amplio: cortometrajes, video clips, animación, cine, fotografía, diseño Web, CD’s
interactivos, documentales, etc.
La dificultad de dicha elección radicaba en el desconocimiento global que tenía del Curso
Tecnología da Comunicação Multimedia. Al ser un estudiante extranjero con una beca
Erasmus, he tenido acceso a la realización de este proyecto sin haber cursado los 4 años
9
Rafael Campillo Lorenzo.
TCM-SPC (2005-2006)
“Cavaleiro dos Céus”
Jogo de computador2D
correspondientes al curso. Por ello desconocía hasta que punto estaba o no preparado para
la realización del proyecto. Mi orientador y yo creímos oportuno compaginar los
conocimientos del curso que estudio en España (Ingeniería Informática) con los de aquí.
El siguiente paso fue elegir un juego en 2 dimensiones.
Para ello usó un programa emulador de máquinas recreativas. El Multiple Arcade Machine
Emulator (emulador múltiple de máquinas recreativas), también conocido por sus siglas
MAME, es un emulador de máquinas recreativas; máquinas de videojuegos que funcionan
con monedas y que suelen estar en lugares públicos (bares, boleras, salones recreativos...).
Para hacer funcionar un juego, se requiere su correspondiente ROM (archivo con una
imagen de la ROM de la máquina, que contiene el juego en sí). Es un programa libre y
gratuito.
De entre todos ellos se escogió un tipo de juegos de aviones (scroll) como base para
comenzar a trabajar, y que dio pie a gran parte de los objetivos que se han marcado para la
realización del proyecto.
1.1.2. Motivación
Siempre he creído que los computadores son una herramienta para conseguir unos fines que
nos marquemos, para facilitarnos la vida, un medio con el que poder desarrollar nuestro
poder imaginativo, y nunca al contrario. Estudiando Ingeniería Informática en España mi
sensación era la opuesta, es decir, yo era el siervo y esclavo del computador.
Aquí se me ha brindado la oportunidad de comenzar a utilizar los ordenadores de una forma
más creativa al realizar este curso; curso que por otra parte no tiene equivalencia en España.
Poder realizar un proyecto de fin de curso con resultados tan visibles e inteligibles como es
la creación de un juego de computador arcade, como aquellos con los que jugaba en la
10
Rafael Campillo Lorenzo.
TCM-SPC (2005-2006)
“Cavaleiro dos Céus”
Jogo de computador2D
infancia, me llenaba de satisfacción, y a la vez suponía un reto tener que manejar un
lenguaje de programación hasta entonces desconocido para mí como Java, el manejo de
programas de diseño gráfico para la parte gráfica del juego, y el hecho de tener que
investigar en un área del conocimiento tan atrayente e interesante como es el mundo de los
videojuegos y sus distintas técnicas de creación.
Además todo esto se complementaba a la perfección con el resto de las disciplinas que
estudio durante este año en el curso de Tecnologías de Comunicação Multimedia, ya que
abarcan desde el manejo de programas enfocados al tratamiento de las imágenes y el diseño
gráfico hasta el estudio del lenguaje Java.
Otra motivación es la posibilidad inmediata de enfocar mi futuro laboral hasta este año
incierto, en una de estas áreas creativas (diseño gráfico, computación gráfica, programación
de videojuegos…)
,9 ;
# <= 2
La finalidad de este proyecto es la iniciación en un mundo apasionante y desconocido para
mí como el de la programación de videjuegos y conseguir encaminar mis conocimientos de
programación anteriores a este año hacia las tecnologías multimedia; y todo ello mediante
la creación de un juego de computador en dos dimensiones y el estudio de las técnicas y
teorías necesarias para su creación.
Algunos objetivos que se marcaron al comienzo del proyecto son:
El tratamiento de las imágenes en los juegos (sprites) y su desplazamiento por la
pantalla (trayectorias).
La visualización de dichas imágenes y su animación (frames)
La gestión de eventos en el juego
11
Rafael Campillo Lorenzo.
TCM-SPC (2005-2006)
“Cavaleiro dos Céus”
Jogo de computador2D
,9>9
El documento se estructura en una parte inicial introductoria en la que se especifica el
dominio o contexto del tema a tratar, las motivaciones así como finalidad, objetivos y
resultados a alcanzar.
En el siguiente bloque se pasa al cuerpo central del documento, hablando sobre la historia
de los juegos arcade y haciendo una breve presentación del trabajo, su descripción (general
y por bloques), y las técnicas y algoritmos estudiados para la realización de juegos en dos
dimensiones.
A continuación viene un bloque que trata sobre la implementación. Se dedica un capítulo a
las herramientas usadas (lenguaje de programación Java y entorno de desarrollo integrado
Eclipse) y a algunas características de los lenguajes Orientados a Objetos (abstracción,
encapsulación, herencia y polimorfismo).
Se comentando en todos estos apartados técnicas usadas para la realización de la práctica y
alternativas a dichas técnicas.
En el último apartado del documento se muestran los resultados y las conclusiones
extraídas de la realización del proyecto.
12
Rafael Campillo Lorenzo.
“Cavaleiro dos Céus”
TCM-SPC (2005-2006)
9
9,9 ?
Jogo de computador2D
&
7
2
7&
=
Un videojuego (llamado también juego de vídeo) es un programa informático, creado
expresamente para divertir, basado en la interacción entre una persona y un aparato
electrónico donde se ejecuta el videojuego. Éstos recrean entornos virtuales en los cuales el
jugador puede controlar a un personaje o cualquier otro elemento de dicho entorno, para
conseguir uno o varios objetivos por medio de unas reglas determinadas. [www_01]
Los videojuegos pueden ser grabados en algún medio de almacenamiento (como un
cartucho, una tarjeta, un disquete, un CD, etc.) para ser ejecutados en un aparato específico.
El hardware que ejecuta los videojuegos puede ser desde una computadora a un artefacto
especialmente creado para ello, como las videoconsolas o las máquinas arcade, pasando por
teléfonos móviles (celulares) y otros dispositivos electrónicos. [www_01]
Los videojuegos como arcade nacieron en 1971 cuando Nolan Bushnell comenzó a
comercializar Computer Space, una versión de Space War, en Estados Unidos, aunque es
posible que se le adelantara Galaxy War otra versión arcade de Space War aparecida a
principios de los 70 en el campus de la universidad de Standford.
“Arcade” es el término genérico usado por los angloparlantes y extendido para el resto del
mundo, pero recibe distintas denominaciones dependiendo el país.
Arcade son las grandes maquinas disponibles en sitios comerciales públicos como
restaurantes, locales, centro comerciales, bares y sitios especializados para jugar
videojuegos. Las máquinas son muebles con algunos controles como un joystick y botones,
o una pistola o un volante dependiendo el juego. Una característica común, es la escasa
duración de las partidas llamadas “creditos” (credit en inglés) que en el argot de este mundo
significa las continuaciones posibles de seguir jugando por tiempo o por perder todas las
vidas; la poca duración asegura que el jugador vaya introduciendo sus monedas o tarjetas.
13
Rafael Campillo Lorenzo.
TCM-SPC (2005-2006)
“Cavaleiro dos Céus”
Jogo de computador2D
También se evita la complejidad para enganchar a cualquier persona. Los primeros
videojuegos salieron en arcade y computadoras (ordenador) antes que en las llamadas
consolas, así que son parte esencial de la historia del videojuego. [www_02]
En la década de los 80 y 90, los arcades eran considerados la “prueba de fuego” para
mostrar todo el potencial gráfico de un videojuego o innovaciones, que eran limitadas por
los controles de consolas y ordenador o simplemente para que mostrara una sensación más
real y envolvente que la que se podría vivir manejando un teclado, en especial las cabinas
hidráulicas de algunos simuladores aéreos, dos o más pantallas y cualquier otro accesorio
difícil de implementar en el sector domestico.
Debido a la rentabilidad y avance de tecnología en las consolas y computadoras que han
llegado a tener un hardware superior al arcade, la posibilidad de jugar online y otros
motivos, las maquinas de arcade han ido perdiendo popularidad hasta casi desaparecer.
En otros usos, el término “arcade” se refiere a los videojuegos clásicos o que recuerdan a
las maquinas del mismo nombre. También se usa para diferenciar a los simuladores;
Algunos géneros en las maquinas de arcade son: deportivos, simuladores aéreos, de
carreras, de acción, de peleas, plataformas, alfombras de baile, juegos de carta, aventuras y
en menor medida puzzles.
Los videojuegos tipo Side-Scrolling son una colección de videojuegos en los que las únicas
direcciones permitidas son arriba, abajo, izquierda y derecha. Existe también un grupo de
enemigos que pueden ser destruidos o esquivados, la acción es vista desde un único ángulo
de cámara y los caracteres se mueven generalmente desde el lado izquierdo hacia el lado
derecho de la pantalla para alcanzar sus metas.
Tile-based game o videojuegos basados en baldosas, tienen su dominio dividido en un
número discreto de baldosas – cuadrados, hexágonos, etc. – y la posición del jugador es
14
Rafael Campillo Lorenzo.
“Cavaleiro dos Céus”
TCM-SPC (2005-2006)
Jogo de computador2D
fijada en un azulejo concreto. El movimiento se hace azulejo a azulejo, y el número de
direcciones en las que el jugador puede progresar es limitado. En un “entorno continuo”, la
posición es representada por coordenadas en punto flotante, lo que puede representar
cualquier localización en el dominio de un juego. El jugador también es libre de avanzar en
cualquier dirección.
En estos juegos las xs y las ys representan columnas y filas en una malla que abarca el
dominio del juego. En un dominio discreto serían valores enteros y en un entorno contínuo,
las xs y las yx (y zs si se hablase de un juego en 3 dimensiones) serían números reales
representando las coordenadas en un sistema de coordenadas cartesianas.
9 9"
<=
Por tanto el tipo de juego que se ha desarrollado es un juego arcade de aviones con scroll de
pantalla para simular el avance del avión por los distintos escenarios. En ese avance se
dedica a luchar contra aviones o grupos de aviones enemigos que se desplazan por la
pantalla con trayectorias aleatorias.
Tanto el avión del jugador como los aviones enemigos tienen la capacidad de disparar.
Cada vez que un avión enemigo es alcanzado por disparos del avión del jugador, explota,
mientras que si el avión del jugador es alcanzado va perdiendo vida hasta perderla toda y
explotar.
9>9
2.3.1. Sprites
Se puede decir que un sprite es un elemento gráfico determinado (una nave, un coche,
etc...) que tiene entidad propia y sobre la que se pueden definir y modificar ciertos
atributos, como la posición en la pantalla, si es o no visible, etc.
15
Rafael Campillo Lorenzo.
TCM-SPC (2005-2006)
“Cavaleiro dos Céus”
Jogo de computador2D
Un sprite es un gráfico que se mueve de manera independiente por la pantalla. Puede ser
animado y moverse a la vez. Además de la animación, o de la imagen, un sprite estará
compuesto por dos características principales: la posición y la velocidad. [Brackeen2004]
Los sprites (en inglés ‘duendecillos’) son un invento de Jay Miner. Se trata de un tipo de
mapa de bits dibujados en la pantalla de ordenador por hardware gráfico especializado sin
cálculos adicionales de la CPU. [www_03]
Típicamente, los sprites son usados en videojuegos para crear los gráficos de los
protagonistas, o para producir una animación, como un personaje corriendo, alguna
expresión facial o un movimiento corporal.
Con el paso del tiempo el uso de este término se extendió a cualquier pequeño mapa de bits
que se dibujase en la pantalla.
Los sprites han ido evolucionando a lo largo de la historia de los videojuegos. En un
principio, mientras algunos eran generados a computador, otros eran dibujados a mano para
posteriormente ser traspasados al computador. Con la llegada de los videojuegos en 3D, el
uso de sprites se ha comenzado a dejar de lado, al ocupar su puesto personajes poligonales.
[www_03]
2.3.2. Coordenadas polares. Distancia entre dos puntos y cambios de coordenadas
polares – cartesianas
Para poder construir toda la parte referente a las trayectorias de los sprites y sus
comportamientos, se hizo necesaria la compresión de conceptos matemáticos básicos para
la computación gráfica como son el cálculo de distancias entre dos puntos, ángulos,
conversión de coordenadas polares a cartesianas y viceversa, etc.
16
Rafael Campillo Lorenzo.
“Cavaleiro dos Céus”
TCM-SPC (2005-2006)
Jogo de computador2D
Tal y como se representa en la Figura 2, la distancia horizontal entre dos puntos es c-a y
la distancia vertical es d-b, por lo tanto, como la distancia entre los puntos es la hipotenusa,
del triángulo formado:
. [www_04]
Figura 1 – Distancia entre dos puntos
El sistema más utilizado para localizar un punto suele ser el de las coordenadas cartesianas,
pero hay otro muy utilizado también: el de coordenadas polares. En este método se utiliza
la distancia del punto al origen, medido sobre el segmento que los une, y el ángulo que
forma dicho segmento con uno de los ejes. Véase la Figura 3:
Figura 2 - Coordenadas polares de un punto
17
Rafael Campillo Lorenzo.
“Cavaleiro dos Céus”
TCM-SPC (2005-2006)
Jogo de computador2D
Si (x,y) son las coordenadas cartesianas de un punto, las coordenadas polares de ese punto
serán
y
= arctg y/x. [www_04]
Si (r, ) son las coordenadas polares de un punto, las coordenadas cartesianas serán: x = r
cos( ), y = r sen( ). [www_04]
2.3.3. Imágenes. Formatos de fichero
A la hora de usar imágenes se ha de tener en cuenta la transparencia de éstas para su
utilización. Existen tres tipos de transparencia de imagen:
Opaca: Cada píxel de la imagen es visible.
Transparente: Cada píxel en una imagen puede ser o completamente visible o
completamente transparente con lo que el fondo blanco de un sprite podría ser
transparente, que es como se mostraría.
Traslúcida: Los píxeles pueden ser parcialmente transparentes. Opcionalmente se
pueden hacer traslúcidos los bordes de una imagen para que ésta fuese anti-aliased.
La java runtime soporta tres formatos raster diferentes, y se pueden leer con apenas
esfuerzo. Estos tres formatos son GIF, PNG, y JPEG. [Knudsen1999]
GIF: las imágenes GIF pueden ser u opacas o transparentes y tiene 8 bits de color o
menos. Aunque GIF tienen alta compresión imágenes gráficas sin mucha variación
de color, PNG supera la funcionalidad del formato GIF.
PNG: Las imágenes PNG pueden tener cualquier tipo de transparencia: opaca,
transparente o traslúcida. También, las imágenes PNG pueden tener cualquier
profundidad de bit, hasta 24bits de color. El porcentaje de compresión para
imágenes PNG de 8bits es similar al de imágenes GIF.
18
Rafael Campillo Lorenzo.
TCM-SPC (2005-2006)
“Cavaleiro dos Céus”
Jogo de computador2D
JPEG: las imágenes JPEG sólo pueden ser de 24bits de profundidad y opacas. JPEG
tiene una alta compresión para imágenes fotográficas, pero es un algoritmo de
compresión con pérdidas, con lo que la imagen no es una réplica exacta de la fuente
original. [Brackeen2004]
9@9 &A
=
Se comentan a continuación algunas técnicas típicas a tener en cuenta en el desarrollo de
juegos tipo arcade:
2.4.1. Active Rendering (Rendering activo)
Para implementar una animación en java, se necesita una forma de actualizar
continuamente la pantalla de una manera eficiente. Confiar en el método paint() para
hacer cualquier tipo de rendering implica llamar al método repaint() para crear el evento
AWT que envía un hilo o thread para repintar la pantalla, pero esto puede causar retrasos
porque el hilo AWT puede estar ocupado haciendo otras cosas. [Brackeen2004]
Otra opción es usar Active Rendering. Active Rendering es un término para describir el
hecho de pintar directamente sobre la pantalla en el hilo principal. De esta manera se tiene
el control cuando la pantalla realmente se pinta, simplificándose el código bastante.
Para usar la técnica de active rendering, se usa el método Component’s getGraphics ()
para obtener el contexto gráfico de la pantalla:
Graphics g = screen.getFullScreenWindow().getGraphics();
Draw(g);
g.dispose();
19
Rafael Campillo Lorenzo.
TCM-SPC (2005-2006)
“Cavaleiro dos Céus”
Jogo de computador2D
2.4.2. Carga tardía
Cargar una imagen dentro del propio método paint() sería una manera muy ineficiente de
cargar imágenes ya que lo que se está haciendo es cargar la imagen cada vez que se
redibuje (repaint()).
public void paint(Graphics g) {
BufferedImage imagenSprite = loadImage("res/imagenSprite.gif");
g.drawImage(imagenSprite, x, y,this);
}
Se podría pensar que lo ideal es cargar la imagen en el constructor de la clase, pero si el
juego fuese un applet y se tuviese una gran cantidad de imágenes de distintos sprites y
niveles, cuando el usuario descargase las clases Java del juego, se quedaría esperando
mucho tiempo a que se efectuase dicha descarga, pudiendo darse el caso de que muchas de
esas imágenes descargadas nunca llegasen a utilizarse porque el jugador no alcance el nivel
en que aparecen.
Por este motivo se suele utilizar una técnica llamada carga tardía, que consiste en cargar la
imagen una única vez, pero aplazar este instante hasta el momento en que realmente se hace
necesario visualizar esa imagen. Un ejemplo podría ser el siguiente:
public BufferedImage imagenSprite = null
public void paint(Graphics g) {
if (imagenSprite==null)
imagenSprite = loadImage("res/imagenSprite.gif");
g.drawImage(imagenSprite, x, y,this);
}
20
Rafael Campillo Lorenzo.
TCM-SPC (2005-2006)
“Cavaleiro dos Céus”
Jogo de computador2D
Aun así, comprobar en todas las posibles situaciones donde pueda surgir la necesidad de
utilizar una imagen, si está cargada o no, es ineficiente. Para evitar esta situación lo ideal es
utilizar una HashMap. [www_06]
Una HashMap (tabla hash) es una es una colección de listas enlazadas. Nos permite
guardar pares clave-valor de distintos tipos, y luego recuperar esos datos utilizando la
clave. [www_06]
Se podrían tener estos métodos dentro de cada sprite u objeto del juego para que él mismo
se autoabasteciese, pero eso sería ineficiente puesto que podría realizar múltiples cargas de
la misma imagen, mientras que de esta manera sólo se carga una imagen una vez,
comprobando antes de cargarla si ya está cargada, y manteniendo actualizada la caché de
gráficos.
2.4.3. Doble Buffering
Al mostrar gráficos con las técnicas estándar, las imágenes suelen aparecer a trozos o con
parpadeo. El parpadeo de una imagen en la pantalla ocurre porque se está pintando
directamente sobre la pantalla de manera constante. Durante unos instantes el ojo está
viendo la pantalla recién borrada en la que todavía no se ha pintado ningún objeto.
Un buffer es simplemente un área fuera de memoria fuera de pantalla usada para dibujar.
Las aplicaciones Java permiten que los programas dibujen en memoria, para luego ir
mostrando la imagen completa de forma suave. Este es el proceso conocido como doblebuffering, y tiene dos ventajas fundamentales sobre el proceso normal de pintar o dibujar
directamente sobre la pantalla. [Brackeen2004]
21
Rafael Campillo Lorenzo.
TCM-SPC (2005-2006)
“Cavaleiro dos Céus”
Jogo de computador2D
Primera, el usuario ve aparecer de golpe la imagen en la pantalla. Mientras el usuario está
viendo esa imagen, el programa está generando la siguiente para mostrarla a continuación,
y así una y otra vez.
Segunda, la técnica de doble-buffering involucra un objeto Image, que se puede pasar
directamente a varios métodos. Esta capacidad para manipular objetos Image permite
descomponer las rutinas de dibujo en componentes funcionales, en lugar de un enorme
método paint().
Por tanto se puede tener en memoria una imagen 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.
La técnica del doble buffer es tan extendida que en el JDK 1.4 se incluyó un mecanismo
automático para realizar este tipo de operaciones, permitiendo además que la visualización
del buffer se hiciese mediante mecanismos más acelerados dependientes de la plataforma
(como por ejemplo, mover el puntero de memoria de la tarjeta gráfica que indica dónde
comienza el buffer de vídeo en lugar de copiar ese buffer a otra zona de memoria).
[Brackeen2004]
2.4.4. Page flipping
Dibujar usando double buffering dura el tiempo que se tarda en copiar la imagen del buffer
a la pantalla. Con una resolución de 800x600 y una profundidad de 16 bits se tendrían
800x600x2 bytes, o 938KB. Esto es cercano al megabyte de memoria que tiene que ser
arrastrado a una velocidad cercana a los 30 frames por segundo. Aunque copiar esa
cantidad de memoria es una tarea suficientemente rápida para muchos juegos, se asume el
riesgo de actualizar el buffer sin haber terminado de copiar dicho buffer a la pantalla.
22
Rafael Campillo Lorenzo.
TCM-SPC (2005-2006)
“Cavaleiro dos Céus”
Jogo de computador2D
Para evitar esto se utiliza una técnica conocida como Page Flipping, en la que se usan dos
buffers, uno como “back buffer” o buffer de dibujo, y otro como “display buffer” o buffer
visible. [Brackeen2004]
Se usa un puntero de muestra que apunta al buffer que está siendo mostrado. Este puntero
de muestra puede ser cambiado en la mayoría de los sistemas modernos. Cuando se termina
de dibujar en el buffer de dibujo, el puntero de muestra puede cambiarse desde el buffer
visible actual, al buffer de dibujo, con lo que en el instante en que el puntero cambia, el
buffer visible pasa instantáneamente a ser el buffer de dibujo y viceversa. [Brackeen2004]
Por supuesto, cambiar la dirección a la que apunta un puntero es mucho más rápido que
copiar un enorme bloque de memoria a la pantalla con lo que se tiene una gran mejora.
La frecuencia de refresco de un monitor está alrededor de los 75Hz más o menos, lo que
significa que el monitor es refrescado 75 veces por segundo. Podría ocurrir que el buffer
visible fuese copiado en mitad de un refresco de pantalla con lo que parte del antiguo buffer
se mostraría simultáneamente con el nuevo. Este efecto, similar al parpadeo, se conoce
como “tearing”. Ocurre tan rápido que podría no notarse, pero cuando se nota, parece como
lágrimas en algún lugar de la pantalla. Es posible llevar a cabo el cambio de página en el
momento exacto, justo cuando el monitor está apunto de ser refrescado. La clase que
permite implementar este tipo de operación se llama BufferStrategy y se encuentra en el
paquete java.awt.image.
2.4.5. Animación: Fotogramas o Frames
Existe un tipo de animación que sigue el estilo de los dibujos animados (cartoon). Este tipo
de animación es mostrada como una secuencia de imágenes, una tras otra, que es como los
dibujos animados funcionan.
23
Rafael Campillo Lorenzo.
TCM-SPC (2005-2006)
“Cavaleiro dos Céus”
Jogo de computador2D
Las imágenes en una animación pueden ser referidas como “frames”. Cada frame se
muestra durante cierto periodo de tiempo, aunque no necesariamente tienen que ser
mostrados el mismo periodo de tiempo.
La misma imagen puede ser mostrada más de una vez. Además, cuantos más fotogramas o
frames hay, más suave es la animación del propio objeto.
Las animaciones también pueden formar parte de un bucle indefinido en lugar de ejecutarse
una vez. [Brackeen2004]
El bucle de animación (animation loop) sigue los siguientes pasos:
1.- Actualiza la animación
2.- Dibuja en la pantalla
3.- Opcionalmente duerme durante un cierto periodo de tiempo
4.- Vuelve al paso 1.
En código Java, Un bucle de animación podría ser algo así:
while (true){
// Actualizar cualquier animación
actualizarAnimacion();
// Dibujar en la pantalla
Graphics g = screen.getFullScreenWindow().getGraphics();
draw(g);
g.dispose();
//hacer una pausa
try{
Thread.sleep(20);
}
catch (InterruptedException ex){}
}
24
Rafael Campillo Lorenzo.
“Cavaleiro dos Céus”
TCM-SPC (2005-2006)
Jogo de computador2D
Obviamente en un ejemplo real, el bucle de animación no debería estar repitiendo ciclos
indefinidamente, con lo que faltaría una condición de salida del bucle.
Para implementar una animación, se necesita una vía para actualizarla pantalla de una
manera eficiente. …
2.4.6. Transformaciones Afines
Un efecto gráfico interesante a la hora de desarrollar juegos en dos dimensiones en Java, es
rotar, trasladar o cambiar la escala de una imagen. A esto se le conoce como Image
Transform o transformación de la imagen. Translaciones, rotaciones y escalamientos son
transformaciones afines. [Brackeen2004]
Para conseguir todas estas transformaciones se dispone de la clase AfineTransform. Esta
clase transforma los ejes y el origen del sistema de coordenadas en lugar de las formas 2D
en él referenciadas. En este sentido rasterizar una forma 2D antes y después de una
transformación afín produce resultados gráficos distintos.
La clase Graphics2D es donde la transformación realmente se sitúa. Existe un método
especial drawImage() en esta clase que puede tomar una AffineTransform como
parámetro. [Knudsen1999]
2.4.7. Gestión de eventos
Los eventos sólo los reciben aquellos componentes que están interesados en ellos. Para
conseguir esto, se implementa un sistema de “clases escucha” (listeners). Una clase de
escucha es una clase que implementa una interfaz de escucha genérico de un tipo de evento
concreto y que se registra con el objeto productor de eventos.
25
Rafael Campillo Lorenzo.
TCM-SPC (2005-2006)
“Cavaleiro dos Céus”
Jogo de computador2D
Por cada tipo de evento existe una interfaz de escucha para los objetos interesados en dicho
evento. El inconveniente de implementar la interfaz es que, necesariamente, se tienen que
sobrecargar todos y cada uno de los métodos de ella.
Para evitar este inconveniente, existen los adaptadores (Adapters), que son unas clases que
implementan estos interfaces con todos los métodos vacíos. Por cada interfaz existe un
adaptador. [www_08]
En todo programa que tenga un manejador de eventos se pueden ver las siguientes
porciones de código:
1.- En la declaración de la clase de la clase escucha, la declaración de que dicha clase
implementa una interfaz de escucha:
public class MiClase implements KeyListener{
2.- La implementación de los métodos del interfaz de escucha.
2.4.8. Scroll
Muchos juegos ofrecen un aspecto visual muy efectista gracias a un fondo con scroll sobre
el que se desarrolla la acción. Este efecto se consigue de forma sencilla si simplemente en
lugar de borrar la pantalla con un color sólido se rellena con una textura.
El scroll se puede alcanzar modificando el rectángulo que actúa como ancla de la textura,
ya que si se aumenta la coordenada Y [(0, 0, 256, 256), (0, 20, 256, 256)], es
decir, aumentamos la coordenada Y en 20 unidades, el efecto es como si todo el decorado
se hubiese desplazado hacia abajo 20 unidades. Por supuesto, dado que se desea un
desplazamiento suave, se debe aumentar la coordenada en un píxel cada vez.
Esto se puede realizar con una única textura, o con varias texturas manteniendo un vector
de imágenes almacenado en memoria y en vez de actualizar los límites superior e inferior
de una única textura, actualizando los límites de dos texturas. Se han de tener siempre las
26
Rafael Campillo Lorenzo.
TCM-SPC (2005-2006)
“Cavaleiro dos Céus”
Jogo de computador2D
dos texturas en la pantalla pero comprobando que cuando el límite superior de una de ellas
llegue al principio de la pantalla, entra la siguiente textura a continuación, y cuando llegue
a su fin se va fuera de la pantalla.
Para el caso de los juegos basados en baldosas, tiled-based games, se tiene otro tipo de
scroll. La técnica consiste en descomponer un mapa de bits en pequeños objetos gráficos y
a continuación en un mapa del gráfico.
Figura 3 - Scroll basado en baldosas descomponiendo un mapa de bits en pequeños objetos gráficos,
creando un mapa del gráfico.
Si la imagen fuese mucho mayor que el área de visión, todo lo que se tendría que hacer es
recrear el mapa de bits al tamaño del área de visión y dibujar una columna (o una fila
dependiendo del sentido del scroll) de baldosas adicionales. Una vez que la imagen se ha
desplazado una cantidad píxels, se borraría la primera columna del mapa de bits (o la
primera fila dependiendo del sentido) y se redibujaría otra en el lado opuesto del mapa de
bits. Esto implica que se redibuja una pequeña porción de la imagen en cada actualización.
2.4.9. Detección de colisiones
Al realizar un juego es bastante habitual la necesidad de detectar las colisiones entre los
distintos sprites. Este proceso debe ser tan rápido como sea posible ya que normalmente
deberá ejecutarse bastantes veces en un tiempo muy corto, como un frame.
27
Rafael Campillo Lorenzo.
TCM-SPC (2005-2006)
“Cavaleiro dos Céus”
Jogo de computador2D
Un acercamiento habitual es comprobar si los rectangulos que forman el sprite se
intersectan. La clase Rectangle de Java incorpora el método intersects() que permite
comprobar si un rectángulo intersecta con otro. Para ello habría que implementar un
método que nos devolviese el rectángulo que envuelve el sprite en coordenadas absolutas
sobre la pantalla.
Esto conlleva a una gran falta de precisión si la imagen significativa del sprite no cubre
todo el rectángulo, es decir tienen una parte transparente. En esos casos cabe la posibilidad
de que lo que se este superponiendo sea la parte transparente de cada uno de los sprites, lo
que no implicaría ninguna colisión. [www_07]
Por tanto se puede buscar una mejora a la técnica anterior.
El primer paso es obtener los Rectangle que forman cada uno de los sprites. Se supone que
sprite1 y sprite2 son los objetos que modelan los sprites y que ofrecen el método:
Rectangle getRectangle();
Que permite obtener el rectangulo que ocupa el sprite y
BufferedImage getImagen();
Que permite obtener la imagen del sprite con partes transparentes.
Rectangle r1=sprite1.getRectangle();
Rectangle r2=sprite2.getRectangle();
Ahora se comprobaría si los rectángulos se solapan:
r1.intersect(r2);
Esta función devuelve verdadero si hay superposición. Si devuelve falso la rutina habrá
terminado ya que no hay colisión. En el caso de que la función devuelva verdadero, implica
28
Rafael Campillo Lorenzo.
TCM-SPC (2005-2006)
“Cavaleiro dos Céus”
Jogo de computador2D
que los rectángulos se sobreponen pero aun no se sabe si lo hacen las zonas no
transparentes del mismo. [www_07]
Para cada uno de los dos Rectangle se obtiene el Rectangle que intercepta con el otro.
Rectangle ir1=r1.intersection(r2);
Rectangle ir2=r2.intersection(r1);
Ahora se obtienen las zonas afectadas de cada uno de los rectángulos.
int dx=ir1.x-r1.x;
int dy=ir1.y-r1.y;
ir1.setLocation(0,0);
ir1.translate(dx,dy);
dx=ir2.x-r2.x;
dy=ir2.y-r2.y;
ir2.setLocation(0,0);
ir2.translate(dx,dy);
Ya se tienen los Rectangle ir1,ir2 del mismo tamaño y apuntan a las zonas de la imagen
superpuestas de cada uno de los sprites. Se obtienen los Raster del canal alpha de cada
sprite.
WritableRaster ras1=sprite1.getImagen().getAlphaRaster();
WritableRaster ras2=sprite2.getImagen().getAlphaRaster();
Y a continuación se obtienen los int correspondientes a todos los pixels superpuestos de
cada sprite.
int[] dat1=(int[]) ras1.getDataElements(ir1.x,ir1.y,ir1.width,ir1.height,null);
int[] dat2=(int[]) ras2.getDataElements(ir2.x,ir2.y,ir2.width,ir2.height,null);
29
Rafael Campillo Lorenzo.
TCM-SPC (2005-2006)
“Cavaleiro dos Céus”
Jogo de computador2D
Ya se pueden recorrer los vectores y comprobar si en algún caso se cumple que en ambos
vectores el elemento correspondiente al mismo índice es distinto de 0, en cuyo caso existe
una colisión real. Si no se cumple para ninguna pareja de elementos significa que no existe
colisión. [www_07]
int size=dat1.length;
boolean hayColision=false;
for(int nn=0;nn<size; nn++)
if((dat1[nn]!=0)&&(dat2[nn]!=0)) {
haycolision=true;
break;
}
2.4.10. Patrones de movimiento. Algoritmo Estándar
Los patrones de movimiento es una manera simple de crear la ilusión de comportamiento
inteligente. Básicamente, los caracteres se mueven de acuerdo a algún patrón predefinido
que simulan actuaciones más complejas.
El algoritmo de patrones de movimiento estándar usa listas de vectores de instrucciones
codificadas o instrucciones de control, que le indican al carácter cómo se debe mover a
cada paso en el bucle del juego. El vector es indexado cada vez a través del bucle principal
para que un nuevo conjunto de instrucciones sea procesado cada vez. [Bourg2004]
Ejemplo de un típico conjunto de instrucciones de control:
ControlData{
double turnRight;
double turnLeft;
double stepFoward;
double stepBackward;
};
30
Rafael Campillo Lorenzo.
“Cavaleiro dos Céus”
TCM-SPC (2005-2006)
Jogo de computador2D
En este ejemplo, turnRight y turnLeft podrían contener el número de grados para torcer
a la derecha o a la izquierda, o si fuese un juego tipo Tile (baldosas), en el que el número de
direcciones en el que el carácter podría avanzar está limitado, turnRight y trunLeft
podría significar torcer a la derecha o a la izquierda un incremento.
stepFoward
y stepBackward podrían contener el número de unidades de distancia, o
baldosas, que se avanzaría adelante o atrás.
La estructura de control podría también tener otras instrucciones como armas de fuego,
lanzamiento de bombas, no hacer nada, acelerar, decelerar, entre muchas otras acciones
apropiadas para el juego.
Los datos usados para inicializar estos vectores de patrones pueden ser cargados desde un
fichero de datos o pueden ser codificados dentro del código del juego, todo dependerá del
estilo de programación y del los requerimientos del juego. [Bourg2004]
La inicialización de un vector de patrones podría ser algo así:
Pattern[0].turnRight = 0;
Pattern[1].turnRight = 0;
Pattern[0].turnLeft = 0;
Pattern[1].turnLeft = 10;
Pattern[0].stepFoward = 2;
Pattern[1].stepFoward = 0;
Pattern[0].stepBackward = 0;
Pattern[1].stepBackward = 0;
...
Para procesar este patrón, se necesitará mantener e incrementar un índice al vector de
patrones, cada vez en el bucle principal del juego. Más adelante, cada vez a través del
bucle, las instrucciones de control correspondientes al índice actual en el vector de patrones
deben ser leídas y ejecutadas.
Void GameLoop(void){
...
31
Rafael Campillo Lorenzo.
TCM-SPC (2005-2006)
“Cavaleiro dos Céus”
Jogo de computador2D
Oject.Orientation += Pattern[currentIndex].turnRight;
Oject.Orientation -= Pattern[currentIndex].turnLeft;
Object.x += Pattern[currentIndex].stepForward;
Object.x -= Pattern[currentIndex].stepBackward;
...
}
Como se puede observar, el algoritmo es bastante simple. Por supuesto, los detalles de
implementación variarán dependiendo de la estructura de cada juego.
2.4.11. Persecución y Evasión básicas
El algoritmo más simple de persecución supone corregir las coordenadas del depredador
con respecto a las coordenadas de la presa, de manera que se reduzca la distancia entre sus
posiciones. Este es un método muy común para implementar persecución y evasión básicas.
(En este método, la evasión es virtualmente lo opuesto a la persecución, por lo que en vez
de intentar decrementar la distancia entre las coordenadas del depredador y la presa, se
puede intentar incrementarlas). [Bourg2004]
En código, el método sería algo parecido a lo que se muestra a continuación:
if (predatorX > preyX)
predatorX--;
else if (predatorX < preyX)
predatorX++;
if (predatorY > preyY)
predatorY--;
else if (predatorY < preyY)
predatorY++;
En este ejemplo, la presa está localizada en las coordenadas preyX y preyY, mientras que el
predador está localizado en las coordenadas predatorX y predatorY.
32
Rafael Campillo Lorenzo.
TCM-SPC (2005-2006)
“Cavaleiro dos Céus”
Jogo de computador2D
Durante cada ciclo a través del bucle principal del juego (game loop), las coordenadas del
depredador son chequeadas frente a las de la presa. Si las coordenada x del depredador es
mayor que la coordenada x de la presa, dicha coordenada se decrementa, acercándolo a la
posición x de la presa, y viceversa. El resultado final es que el depredador se va acercando
cada vez más a la presa a cada ciclo del bucle principal. [Bourg2004]
Usando la misma metodología se puede implementar la evasión:
if (preyX > predatorX)
preyX++;
else if (preyX < predatorX)
preyX--;
if (preyY > predatorY)
preyY++;
else if (preyY < predatorY)
predatorY--;
En un Tiled-based game o juego basado en baldosas, un algoritmo básico de persecución
sería el siguiente:
if (predatorCol > preyCol)
predatorCol--;
else if (predatorCol < preyCol)
predatorCol++;
if (predatorRow > preyRow)
predatorRow--;
else if (predatorRow < preyRow)
predatorRow++;
El problema con estas implementaciones tan básicas es que con frecuencia la persecución o
la evasión parecen muy mecánicas ya que no se persigue a la presa en línea recta que es la
dirección más corta. [Bourg2004]
33
Rafael Campillo Lorenzo.
TCM-SPC (2005-2006)
“Cavaleiro dos Céus”
Jogo de computador2D
2.4.12. Inteligencia Artificial en juegos
Existen múltiples técnicas relacionadas con la inteligencia artificial (IA) y que son
ampliamente utilizadas en programación de juegos. El algoritmo estándar o las técnicas
básicas de persecución y evasión serían una forma de simular comportamientos inteligentes
en un juego. [www_05]
Hay, al menos, tres tendencias dentro del campo de la inteligencia artificial.
Redes neuronales
Algoritmos de búsqueda
Sistemas basados en conocimiento
Son tres enfoques diferentes que tratan de buscar un fin común. No hay un enfoque mejor
que los demás, la elección de uno u otro depende de la aplicación. [www_05]
Una red neuronal trata de simular el funcionamiento del cerebro humano. El elemento
básico de una red neuronal es la neurona. En una red neuronal, un conjunto de neuronas
trabajan al unísono para resolver un problema. Al igual que un niño tiene que aprender al
nacer, una red de neuronas artificial tiene que ser entrenada para poder realizar su
cometido. Este aprendizaje puede ser supervisado o no supervisado, dependiendo si hace
falta intervención humana para entrenar a la red de neuronas. Este entrenamiento se realiza
normalmente mediante ejemplos. La aplicación de las redes neuronales es efectiva en
campos en los que no existen algoritmos concretos que resuelvan un problema o sean
demasiado complejos de computar. Donde más se aplican es en problemas de
reconocimiento de patrones y pronósticos.
El segundo enfoque es el de los algoritmos de búsqueda. Es necesario un conocimiento
razonable sobre estructuras de datos como árboles y grafos. Una de las aplicaciones
interesantes, sobre todo para videojuegos, es la búsqueda de caminos (pathfinding). Este
34
Rafael Campillo Lorenzo.
TCM-SPC (2005-2006)
“Cavaleiro dos Céus”
Jogo de computador2D
algoritmo de búsqueda en grafos es llamado A*. El algoritmo A* además de encontrar un
nodo objetivo, se asegura que es el camino más corto. [www_05]
Por último, los sistemas basados en reglas se sirven de conjuntos de reglas y hechos. Los
hechos son informaciones relativas al problema y a su dominio de conocimiento. Las reglas
son aplicables a los elementos del universo y permiten llegar a deducciones simples.
Una máquina de estados está compuesta por una serie de estados y una serie de reglas que
indican en qué casos se pasa de un estado a otro. Estas máquinas de estados nos permitirían
modelar comportamientos complejos en los personajes y elementos de un juego.
Figura 4 - Posibles cambios de estado de un objeto que se desplaza por la pantalla
35
Rafael Campillo Lorenzo.
“Cavaleiro dos Céus”
TCM-SPC (2005-2006)
>9
Jogo de computador2D
" :7
En este capítulo se describe y explica la práctica realizada, su código y agrupamiento
lógico.
>9,9
6
El hecho ya comentado de que cualquier aplicación Java pueda ejecutarse en cualquier
plataforma de ejecución para la que exista una implementación de la JVM (Java Virtual
Machine), y que el lenguaje Java sea un lenguaje de programación Orientado a Objetos,
hacían de éste el lenguaje idóneo para el desarrollo del juego.
El primer paso en cualquier programa de java es la clase principal con el punto de entrada
al programa. La clase principal encargada de gestionar todo el programa, creando,
manejando y destruyendo todas las instancias de clase, es la Clase Jogo2D. Dicha clase
contendrá la función main().
La clase Jogo2D inicializa el programa y todos los objetos que usa el programa, y a
continuación llama a la función Game() que no es más que un bucle que se ejecuta hasta
que la partida termine, caso que se da cuando ocurra alguna condición de salida. Dentro de
ese bucle se realizan todos los cálculos necesarios y se diseña en pantalla las imágenes que
se van a mostrar.
Aprovechando las características de la POO se pudieron clasificar todos los entes que
aparecían en el juego en objetos, y a un nivel superior, en jerarquías de clases.
Objetos obvios que hay que representar serían todos aquellos que aparecen en la pantalla,
es decir las imágenes. Por tanto una primera clase de la cual heredarían todos los objetos
que apareciesen en la pantalla sería la clase Sprite. De ella heredarían otras clases como
Jugador, Enemigo, Tiros,
etc.
36
Rafael Campillo Lorenzo.
“Cavaleiro dos Céus”
TCM-SPC (2005-2006)
Jogo de computador2D
Por lo tanto ya se tiene la clase principal Jogo2D con la función main(), que controla todo
el programa, y una jerarquía de clases que define y representa todos los objetos con vida en
la pantalla.
Más clases necesarias son aquellas que gestionan el acceso a los gráficos y el sonido:
GraficosCache
y SonidoCache, de actualizar y controlar la sucesión de imágenes de
fondo del escenario a implementar, como sería la clase Scroll, otra clase para capturar
dichas imágenes de fondo y por último una interfaz que sería Escenario, para que pueda ser
accedida desde cualquier clase que lo desee y permitir así que distintas jerarquías presenten
características comunes, puesto que en Java no se permite la herencia múltiple.
Para la creación del juego de aviones 2D ha sido preciso la construcción de 15 clases:
Clase Bomba
Clase Comportamiento
Clase Enemigo
Clase Escenario
Clase Fondos
Clase GraficosCache
Clase Jogo2D
Clase Jugador
Clase PuntosExtra
Clase RecursosCache
Clase Scroller
Clase SonidoCache
Clase Sprite
Clase Tiros
Clase TirosEnemigo
Esta división hecha en clases se puede hacer a un nivel más alto de abstracción, agrupando
distintas clases en bloques de clases dependiendo de su funcionalidad.
37
Rafael Campillo Lorenzo.
“Cavaleiro dos Céus”
TCM-SPC (2005-2006)
>9 9
Jogo de computador2D
B C
Existen 5 grandes bloques bien diferenciados:
Un primer bloque compuesto por la clase principal Jogo2D y la clase Escenario. La
primera controla y coordina todo el funcionamiento del juego, y la segunda hace de interfaz
para simular la herencia múltiple, que no está permitida en Java, con lo que distintas clases
podrán acceder a funciones y características comunes.
Un segundo bloque sería el compuesto por todos los sprites que aparecen en la pantalla.
Para ello se tiene la superclase Sprite de la que heredan 6 clases más (Jugador, Tiros,
Enemigos…).
Otro bloque lo compondrían las clases Fondo y Scroll, que son las encargadas de capturar
las distintas imágenes que compondrán los escenarios y de producir el efecto de scroll o
desplazamiento de la imagen en pantalla mediante la mudanza de imágenes y sus
coordenadas de diseño en la pantalla.
El siguiente bloque abarca todo lo referente a la captura de gráficos y sonidos. Está
compuesto por las clases GraficosCache y SonidosCache, la cuales heredan un
comportamiento común de la clase RecursosCache.
Para finalizar una de las clases más importantes y que compone por sí sola un bloque, es la
clase Comportamiento, encargada de controlar todas las trayectorias de los sprites por la
pantalla.
38
Rafael Campillo Lorenzo.
TCM-SPC (2005-2006)
“Cavaleiro dos Céus”
Jogo de computador2D
>9>9
Muchos de los conceptos orientados a objetos de Java son heredados de C++, el lenguaje en
el que está basado, pero también toma prestados muchos conceptos de otros lenguajes
orientados a objetos.
Todo en Java son clases. Una clase en Java encapsula un conjunto de datos y un conjunto
de operaciones. Los valores son representados por los atributos de la clase, y las
operaciones por los métodos de la clase. En java una definición de una clase introduce un
nuevo tipo. Las instancias de ese tipo se llaman Objetos. [Coelho2003].
3.3.1. Jerarquía de Clases
Figura 5 - Jerarquía de Clases
39
Rafael Campillo Lorenzo.
“Cavaleiro dos Céus”
TCM-SPC (2005-2006)
Jogo de computador2D
3.3.2. Class Jogo2D
Un juego básicamente de forma continua está haciendo lo siguiente:
Actualizar el “estado del mundo” o el “escenario” (realizarCalculos ())
Si es preciso, refrescar la pantalla (diseñar ())
Volver a actualizar el escenario.
Y eso es lo que hace la rutina principal del juego: game(), actualizar las coordenadas de
los fondos que componen los escenarios, y actualizar la pantalla, todo ello dentro de un
bucle controlado por un contador de tiempo. Tenemos el método ini() que inicializa el
programa y el bucle principal estará en una rutina game(). El método que pinta la pantalla
es el método paint(), que siempre realizará dos funciones independientes dentro de él:
realizarCalculos()
y desenhar().
En el primer paso (realizarCalculos()) se efectúan todos los cálculos necesarios para
actualizar el estado del juego. Por supuesto todo esto no se hace en la misma rutina, pero sí
se puede pensar que constituye una etapa claramente diferenciada de la siguiente, en la que,
si ha habido cambios en lo que el jugador está viendo, entonces se dibuja de nuevo:
Es donde se cambian y calculan todas las trayectorias de los enemigos, de los disparos,
bombas y en definitiva donde se actualiza la posición de todos los sprites que aparecen en
pantalla.
Se efectúan las acciones del jugador (movimientos por la pantalla).
Se controla la aparición o desaparición de nuevos elementos en el juego (bolas de
puntos extra, nuevos disparos, bombas…).
Se controla si hay un cambio de fase y si se ha terminado el juego.
Se chequean todas las colisiones entre los distintos sprites del juego.
40
Rafael Campillo Lorenzo.
TCM-SPC (2005-2006)
“Cavaleiro dos Céus”
Jogo de computador2D
La segunda parte del diseño se encarga de pintar todo lo que vemos en pantalla:
La pantalla inicial que hay al principio de cada fase.
La barra de estado del juego, que está compuesta por la puntuación del jugador, la
vida que le queda y el número de bombas del que dispone.
Los Escenarios del juego.
Todos los sprites del juego.
Los mensajes de fin de partida, fin del juego, fin de fase…
También se lleva a cabo en esta clase la gestión de los eventos para controlar el teclado y
los mandos del juego.
3.3.3. Clase GraficosCache
Esta clase es la parte del programa independiente de las demás que se dedica gestionar una
“caché de gráficos”. Su única interacción es cargar y proporcionar gráficos a quien lo
necesite. Ambos métodos son heredados de la clase RecursosCache.
Además posee un método llamado createCompatible(), que permite usar imágenes en
formato compatible. Una imagen compatible es una imagen en memoria que tiene las
mismas características (o al menos muy similares) al modo de vídeo nativo que se está
mostrando en ese momento, en términos de bits por píxel, transparencia, etc.
Las imágenes compatibles son mucho más rápidas para dibujar que cualquier otro formato.
41
Rafael Campillo Lorenzo.
TCM-SPC (2005-2006)
“Cavaleiro dos Céus”
Jogo de computador2D
3.3.4. Clase SonidoCache
Los sonidos son un recurso más para el programa, de forma que lo que necesitamos es una
clase que gestione una “caché de gráficos” de forma muy similar a la caché de sprites que
gestiona la clase GraficosCache.
Será la encargada de localizar y cargar los archivos de sonido. Su código es muy similar a
GraficosCache,
pero devuelve AudioClips en lugar de BufferedImages. También
proporciona dos métodos adicionales que son playSound(), para reproducir un sonido una
única vez y loopSound() para reproducir un sonido cíclicamente.
3.3.5. Clase RecursosCache
Dado que ambas clases, GraficosCache y SonidoCache, comparten gran parte de su
funcionalidad, se generaliza el comportamiento de ambas en la clase RecursosCache.
Se tiene la rutina cargarRecurso(), que recibirá como parámetro un nombre de un sprite o
sonido que se necesite y devolverá el recurso (imagen o sonido), cargándolo si es necesario.
Puesto que puede haber muchas imágenes o sonidos, la rutina tendrá que recordar qué
recursos están cargados y cuáles no.
Para ello nada mejor que una HashMap que asocie el nombre de cada sprite o sonido con su
imagen o sonido en memoria
3.3.6. Clase Escenario
El escenario es el que de alguna forma coordina las cosas que ocurren en el juego, sabe
cuántos enemigos hay, cuantas balas, en qué nivel se está, etc...
Contiene las constantes generales del juego (largura, altura, altura_juego, velocidad) y
métodos para acceder a los gráficos, sonidos, al jugador y para añadir un sprite al vector de
sprites desde cualquier localización en el juego.
42
Rafael Campillo Lorenzo.
“Cavaleiro dos Céus”
TCM-SPC (2005-2006)
Jogo de computador2D
Java no permite la herencia múltiple, por lo que una clase tan sólo puede heredar de una
única clase. Existen situaciones en las que sería deseable que clases de varias jerarquías
presenten características, comportamientos comunes, de ahí la necesidad de las interfaces,
que no son más que una plantilla con métodos y atributos que será usada por clases
distintas a la vez. La clase Escenario es una interfaz.
Si la interfaz presenta el modificador de acceso public, podrá ser accedida desde cualquier
clase o interfaz en cualquier paquete, como es el caso de Escenario. Si no, tendrá acceso
por defecto, es decir, será visible para las clases e interfaces de su paquete.
Una interfaz puede declarar en su cuerpo métodos abstractos y/o variables constantes.
Todos los métodos declarados en una interfaz son implícitamente públicos y abstractos y
todas las variables declaradas en una interfaz son implícitamente públicas, estáticas y
finales.
Una interfaz proporciona la descripción de un comportamiento común a un conjunto de
clases. Son las clases las encargadas de implementar dicho comportamiento, a lo que se
denomina implementación de una interfaz.
3.3.7. Clase Sprite
Ya se ha comentado en el estado del conocimiento qué es un sprite y cuáles sus
características principales. Existen ciertas características comunes a todos los sprites del
juego por lo que esta clase será capaz de encapsular prácticamente cualquier cosa “activa” o
“viva” sobre el escenario.
Los principales atributos de esta clase son todos aquellos que permitirán situar a un sprite
en la pantalla y realizar cualquier tipo de trayectoria:
posX, posY: Posición
vx, vy:
del objeto sobre la pantalla.
velocidad de desplazamiento en cada coordenada
43
Rafael Campillo Lorenzo.
“Cavaleiro dos Céus”
TCM-SPC (2005-2006)
ox, oy, cx, cy:
Jogo de computador2D
origen del objeto y centro de trayectorias curvilíneas.
angulo, radio, tipoTrayectoria:
ángulo, radio y tipo de trayectoria.
Largura, altura:
tamaño del objeto.
nombresSprites:
vector de nombres de imágenes que identifiquen al objeto sobre la
pantalla para hacer animación. Dado que los fotogramas es algo que queremos que tenga
cualquier objeto del juego (disparos, nave, enemigos, colisiones…) se añade esa
funcionalidad a la clase Sprite. El atributo nombresSprites es una matriz de nombres de
gráficos (los distintos fotogramas que dotarán de movimiento a nuestro objeto) en lugar de
un único gráfico. Adicionalmente, el método actuar() se encarga de incrementar el
número de fotograma cada vez. Se rellena la matriz de sprites con las distintas imágenes y
cada vez que se pinta aumenta el índice del vector (frame actual) para capturar y pintar la
imagen siguiente. Cuando el índice llegase al final del vector se volvería a inicializar con el
primer elemento del vector.
3.3.8. Clase Enemigo
El enemigo va a ser cualquier objeto enemigo, que en este caso serán los aviones contra los
que se enfrente el jugador, pero se podría ampliar su funcionalidad a cualquier tipo de
objeto, ya que en esencia serían lo mismo con distintas velocidades y posiciones.
Tienen una posición sobre la pantalla
Tienen un tamaño (una anchura y una altura)
Tienen una trayectoria
Ejecutan un comportamiento, una acción.
Entre sus métodos cabe reseñar el método expandir(), que genera un objeto de tipo
PuntosExtra
cuando un enemigo muere y tiene su atributo booleano puntosExtra a
“verdadero”. Dicho atributo ha sido puesto a verdadero de forma aleatoria por lo que no
todos los enemigos crean una instancia de PuntosExtra al desaparecer.
44
Rafael Campillo Lorenzo.
TCM-SPC (2005-2006)
“Cavaleiro dos Céus”
Jogo de computador2D
3.3.9. Clase Jugador
El jugador es un sprite que además puede ser controlado por el usuario mediante el teclado.
Se puede desplazar por la pantalla mediante la pulsación de las teclas cursores. Las
direcciones toma son los ocho puntos cardinales resultado de las cuatro teclas cursores y la
combinación de ellas dos a dos.
Siempre que la tecla “espacio” sea pulsada se genera una nueva instancia de Tiros que se
añade al vector de sprites del juego. Si la tecla pulsada es la “b” genera una ocho instancia
de Bombas en las ocho direcciones de los puntos cardinales.
Como atributos a destacar tiene tres sprites llamados cima, esquerda y direita, que serán los
que se desplacen cuando los cursores de arriba o abajo, izquierda y derecha sean pulsados.
3.3.10. Clase Tiros
Esta clase representa los disparos provenientes del avión del jugador. Por ser los tiros
objetos que se mueven por la pantalla también descienden de la clase Sprite. Los disparos
aparecen cuando se pulsa la barra espaciadora. Esto provoca un evento que crea un objeto
disparo.
Los disparos del jugador se mueven en línea recta y desparecen al salir de la pantalla por su
borde superior.
3.3.11. Clase Bomba
La clase Bomba también desciende de Sprite y será el otro tipo de armamento del que
disponga el jugador. Responde a la pulsación de la tecla “B”, y en ese instante se disparan
ocho bombas en las ocho direcciones cardinales.
45
Rafael Campillo Lorenzo.
TCM-SPC (2005-2006)
“Cavaleiro dos Céus”
Jogo de computador2D
3.3.12. Clase TirosEnemigo
La clase TirosEnemigo, descendiente de Sprite, va a depender del ángulo del enemigo
porque esa será la dirección que tome. Por tanto en la creación aleatoria de un tiro por parte
de los enemigos se le ha de pasar al objeto TirosEnemigo el ángulo del enemigo y el tipo
de trayectoria.
Si un objeto de esta clase sale de los límites de la pantalla, se elimina. Las posiciones de los
tiros según avanzan se hayan con coordenadas polares, y para pintar dicho tiro se necesita
hacer una transformación.
3.3.13. Clase PuntosExtra
Descendiente de la clase Sprite, crea un objeto que se moverá por la pantalla y que
incrementará en 100 los puntos del jugador si éste es capaz de interceptarlo. Dicho objeto
es creado al morir aviones enemigos elegidos aleatoriamente. El sprite de puntos extra
aparecerá en la misma posición en la que estaba el avión al desaparecer y será trayectoria,
al igual que la de los enemigos, será gestionada por la clase Comportamiento.
3.3.14. Clase Fondos
La clase Fondos se encarga de capturar y devolver las imágenes que serán utilizadas como
escenarios del juego. También almacena los límites inferior y superior mostrados en
pantalla de dichas imágenes para poder desplazarlas por la pantalla y conseguir el efecto de
scroll.
3.3.15. Clase Scroller
Esta clase mantiene un vector que almacenará todas las imágenes que compondrán los
escenarios de cada fase del juego. Por tanto tiene los siguientes atributos vectorFondos,
indice,
fondos,
que indexará el siguiente fondo a aparecer en pantalla, y dos variables de tipo
que serán las que estén siempre visibles.
46
Rafael Campillo Lorenzo.
“Cavaleiro dos Céus”
TCM-SPC (2005-2006)
Jogo de computador2D
Los métodos más importantes de la clase son los métodos actBufferFondos(),
actLimitesFondos(), y update().
actBufferFondos(),Va
mostrando imágenes nuevas del vector de fondos. Para ello juega
con las dos variables fondo1 y fondo2, que se usan para mostrar dos fondos distintos de
forma simultánea en la pantalla, manteniendo el último fondo que se mostraba, y añadiendo
el nuevo.
3.3.16. Clase Comportamiento
La clase Comportamiento es la encargada de controlar todas las trayectorias de los aviones
enemigos y los objetos de puntos extra.
Existen dos tipos de trayectorias: trayectorias rectilíneas y trayectorias curvilíneas.
Las trayectorias rectilíneas tienen su origen en la posición actual del avión enemigo, y su
destino en la posición donde se encontrase el avión del jugador en el momento que se mudó
la trayectoria.
Las trayectorias curvilíneas pueden ser en los dos sentidos, izquierda o derecha con un
centro aleatorio dentro de la pantalla.
El cambio entre las posibles trayectorias es aleatorio y con un contador de tiempo también
aleatorio.
Contiene además una variable contadorGrupo
agrupar los aviones enemigos en
formación. Por lo tanto aparecerán al inicio, los aviones en diferentes escuadrones con
tantos componentes como el atributo contadorGrupo indique.
47
Rafael Campillo Lorenzo.
TCM-SPC (2005-2006)
“Cavaleiro dos Céus”
Jogo de computador2D
A partir del primer cambio de trayectoria en la partida, dichas formaciones se rompen, pero
se siguen asignando distintas trayectorias a los grupos a pesar de que estos no puedan
mantener la formación inicial.
Para conseguir esas formaciones en escuadrón al inicio de cada fase, se establece un origen
imaginario de los distintos aviones de forma ordenada, para que vayan entrando en
formación. El método que consigue esto es public void establecerOrigen(Sprite
s,int i).
48
Rafael Campillo Lorenzo.
“Cavaleiro dos Céus”
TCM-SPC (2005-2006)
@9
"
@9,9
7&
Jogo de computador2D
:7
!
=
Fase1: En una primera fase de desarrollo lo primero que se planteó fue la creación de un
programa en java que permitiese que una imagen se trasladase por la pantalla, es decir, un
programa que consiguiese el scroll o desplazamiento. Scroll consiste en desplazar una
imagen sobre sí misma o bien varias imágenes que den paso las unas a las otras para
alcanzar así el efecto de desplazamiento del escenario deseado.
Además se crearon otros dos programas. Uno que gestionase los eventos de pulsación de
teclas para trasladar un sprite en función de los cursores; y otro que consiguiese animar los
sprites.
Fase 2: En una segunda fase se centró el estudio en las técnicas de scroll para simular el
avance a través de los distintos escenarios.
Para conseguir esto se siguieron varias etapas puesto que en un principio se consiguió el
scroll pero con una única textura.
A continuación se cambió la metodología usada para alcanzar este efecto. En lugar de usar
una única imagen que se desplazaba sobre sí misma, se pasó a usar dos imágenes cargadas
en memoria.
Como el salto se hacía entre dos imágenes distintas, se creyó oportuno tener dos tipos
diferenciados de imágenes que nos permitiesen una transición limpia de fondos sin que se
notase el salto de imagen; una imagen sería sólo agua y la otra sería tierra pero con agua en
la parte superior y en la parte inferior de la imagen para que al pasar de una imagen a otra
la transición fuese siempre del tipo agua-agua.
49
Rafael Campillo Lorenzo.
TCM-SPC (2005-2006)
“Cavaleiro dos Céus”
Jogo de computador2D
La filosofía cambió, pero esto permitió con facilidad pasar a un nivel más alto en el que
cabían dos opciones:
Creación de un vector de imágenes de tierra, siempre guardando las características
especiales ya comentadas para ese tipo de imágenes, donde ambos extremos
superior e inferior de la imagen son agua, y aparte fuera del vector una imagen que
fuese. A continuación bastaba tener una variable aleatoria que indexase el vector
para ir alternando las imágenes del vector con la de agua. Obviamente con esta
opción tendríamos la gran ventaja de tener escenarios distintos (al menos en la
sucesión de imágenes) en cada ejecución del programa ya que la variable que iba
eligiendo la siguiente textura era aleatoria, y la desventaja de que siempre tendría
que ser mediante una alternancia de agua-tierra-agua.
La otra opción, que además ha sido la opción escogida, consistía en tener un vector
de texturas ordenado según su secuencia de aparición. Con ello se podría también
tener tantos vectores como escenarios creados para después cargar los distintos
vectores según fuese interesando (por ejemplo se va cargando un nuevo vector de
imágenes en memoria al pasar a una nueva fase en el juego). Escoger la primera
opción o la segunda no implicaba grandes variaciones puesto que al final lo más
importante era tener conseguida la transición entre dos imágenes.
Por lo tanto el bloque encargado de conseguir el efecto scroll dentro del juego estará
formado por las clases Scroller y Fondos.
La clase Scroller gestiona el fondo que va a aparecer y la clase Fondos va creando los
distintos objetos texturas, tantos como fondos distintos haya. Se va modificando la
componente, teniendo siempre dos texturas en la pantalla, pero se ha de comprobar siempre
que cuando el límite superior de una de ellas llegue al principio de la pantalla ha de entrar
la siguiente textura a continuación, y cuando llegue a su fin se va fuera de la pantalla.
50
Rafael Campillo Lorenzo.
TCM-SPC (2005-2006)
“Cavaleiro dos Céus”
Jogo de computador2D
Fase 3: Sustitución de hilos o threads cuando se pulsa una tecla para que un sprite se
desplace hacia un lado u otro, por la contención de sprites dentro de sprites. Usamos
objetos sprites a modo de atributos. Esto se ha usado en la clase jugador.
Para las colisiones se hizo mismo, es decir, llamar un vector de colisiones dentro de cada
sprite para que se despliegue a modo de fotogramas a la muerte de un objeto. Con esto se
evita la utilización de hilos en el programa.
La última etapa de construcción, se centró en el control de las trayectorias y
desplazamientos de los distintos sprites por la pantalla. Para ello se implementó la clase
Comportamiento.
@9 9 ?
El lenguaje de programación escogido para el desarrollo del juego es el lenguaje Java
1.4.2_10 SDK, por su sencillez y potencia.
El Java Runtime Enviroment (JRE) es el entorno de ejecución de Java. Proporciona API.s
de Java, la máquina virtual de java y los componentes necesarios para ejecutar aplicaciones
y applets escritos en ele lenguaje de programación Java.
El Java 2 Software Development Kit (SDK) o kit de Desarrollo de Software en Java, es un
“superconjunto” del JRE, conteniendo todos los elementos del JRE, pero además añade las
herramientas necesarias para el desarrollo de applets y aplicaciones Java.
Durante las primeras semanas, todo el trabajo realizado para el aprendizaje del lenguaje y
para la implementación de la parte práctica del proyecto se hizo mediante comandos y en
modo consola, utilizando un editor de textos (Ultraedit-32 v10.10b) para escribir los
programas, compilando (javac jogo2d.java) y ejecutándolos (java Jogo2D) desde la consola
(MSDOS).
51
Rafael Campillo Lorenzo.
TCM-SPC (2005-2006)
“Cavaleiro dos Céus”
Jogo de computador2D
Más adelante, y una vez se tuvieron los conceptos básicos del lenguaje asimilados, y la
estrategia de implementación de la práctica a seguir, se decidió usar un entorno de
desarrollo integrado gráfico para Java llamado Eclipse 3.1.
4.2.1. Java 1.4.2_10 SDK
Java es un innovador lenguaje de programación orientada a objetos desarrollado por Sun
Microsystems basado en los lenguajes C y C++, que se ha convertido en el lenguaje elegido
para los programas que necesiten ser ejecutados en una gran variedad de sistemas de
computadores. Por tanto permite crear grandes aplicaciones que corran bajo cualquier
sistema operativo independientemente de la máquina en que se ejecuten. [Horton2003]
Esto es posible ya que un programa Java no se ejecuta directamente sobre nuestra
computadora, sino sobre una hipotética máquina estandarizada llamada Java Virtual
Machine o JVM, que es emulada dentro de nuestro computador por un programa.
Figura 6 – Ejemplo compiladores para distintas plataformas y de la JVM
Un compilador Java convierte el código fuente Java escrito en un programa binario
consistente en una serie de Byte codes. Los Byte codes son instrucciones máquina para la
Java Virtual Machine. Cuando ejecutamos un programa Java, otro programa llamado Java
Interpreter inspecciona y descifra los byte codes para él y se asegura de que no haya fallos
y sea seguro ejecutarlos, para ejecutar a continuación las acciones especificadas en los byte
codes con la Java Virtual Machine. [Horton2003]
52
Rafael Campillo Lorenzo.
TCM-SPC (2005-2006)
“Cavaleiro dos Céus”
Jogo de computador2D
Un intérprete de Java puede ejecutarse solo o ser parte de un navegador Web como
Netscape Navigator, Microsoft Internet Explorer o Mozilla Firefox, donde puede ser
invocado automáticamente para ejecutar applets en una página Web.
Los Applets son pequeños programas incluidos en los navegadores. Esto provee de una
amplia gama de posibilidades a la computación Web Como nuestro programa Java consiste
en byte codes en vez de instrucciones máquina nativas, está completamente aislado del
hardware particular sobre el que se vaya a ejecutar. Cualquier computadora que tenga el
entorno java implementado podrá manejar nuestro programa tan bien como cualquier otra,
y todo ello gracias a que el Java Interpreter hace de intermediario entre nuestro programa y
la capa física de la máquina. En el pasado se penalizaba esta flexibilidad y protección con
la velocidad de ejecución (un programa interpretado de Java se ejecutaba a un 10% de la
velocidad de otro programa en instrucciones máquina equivalente) pero con las
implementaciones actuales de las máquinas Java, la mayoría de la penalización en el
desarrollo ha sido eliminada.
Otra característica importante del lenguaje Java es que es un lenguaje Orientado a Objetos,
haciendo los programas más potentes, fáciles de entender, mantener y de extender en
futuras ampliaciones.
Otras características notables de éste lenguaje de programación son las siguientes:
Es un lenguaje simple, interpretado, distribuido, robusto, seguro, no dependiente de la
arquitectura, portable, de alto rendimiento, multitarea y dinámico.
Algunas características importantes de los lenguajes Orientados a Objetos y por ende de
Java son:
53
Rafael Campillo Lorenzo.
TCM-SPC (2005-2006)
“Cavaleiro dos Céus”
Jogo de computador2D
4.2.2. Abstracción
La abstracción puede ser vista como un mecanismo mediante el cual se obvian los detalles
irrelevantes para fases posteriores y se enfatizan los relevantes. Esto facilita al programador
pensar en el problema a resolver. Existen muchos niveles y tipos distintos de abstracción
(abstracción procedural, abstracción de datos…). Los niveles más altos de la abstracción
esconden más detalles al contrario que los más bajos.
La técnica que se utiliza para obtener la abstracción de datos es la encapsulación de los
mismos en una estructura conocida como clase. [Horton2003]
Al ser la abstracción una característica más genérica e implícita a toda la Programación
Orientada a Objetos, la tenemos presente a lo largo del desarrollo del juego, desde el
momento en que usamos una jerarquía de clases, con sus métodos y atributos.
4.2.3. Encapsulación
La encapsulación u ocultación de la información, permite definir qué atributos y qué
operaciones serán accesibles o visibles para el resto de objetos en el sistema.
Se pueden ocultar atributos y operaciones internas de una clase para que no puedan ser
accedidos, protegiendo las propiedades de un objeto contra su modificación por quien no
tenga derecho a acceder a ellas, solamente los propios métodos internos del objeto pueden
acceder a su estado. [Coelho2003]
Se evitan accesos indebidos y errores difíciles de detectar y solucionar.
Durante el desarrollo del juego aplicamos la encapsulación a la gran mayoría de los
atributos o estructuras de datos de las clases al ser declarados todos ellos como privados a
la clase. Esto implica que no se puede acceder a ellos directamente, si no a través de
métodos que los manejen, siempre y cuando sean definidos.
54
Rafael Campillo Lorenzo.
TCM-SPC (2005-2006)
“Cavaleiro dos Céus”
Jogo de computador2D
4.2.4. Herencia
La herencia permite a una clase heredar un comportamiento y estado de otra clase para
especializarlo de manera adecuada. De esta forma, se permite reutilizar el estado y
comportamiento común de una clase, con lo que tan sólo se tendrá que añadir el
comportamiento específico de la clase que hereda.
La clase derivada hereda todos los atributos y métodos de la clase o clases base. Además
los métodos heredados pueden ser sobrescritos en la clase derivada con nuevos atributos y
funciones.
Java permite que una clase herede el comportamiento y estado de otra clase utilizando en la
declaración de dicha clase la palabra reservada “extends” seguida del identificador de la
clase de la cual se hereda. Java tan solo permite heredar de una única clase, lo que se
denomina herencia simple.
En el desarrollo del juego se han creado dos jerarquías de clases en las que las sublclases
herendan las características de la superclase. Por ejemplo tenemos una superclase
denominada Sprite que contiene las características comunes, es decir, todos los métodos y
atributos comunes a los Sprites que luego son heredados por seis clases que especializan el
comportamiento de la superclase sprite. Esas cinco clases que heredan de sprite son:
Jugador, Enemigo, Tiros, TirosEnemigo, Bomba y PuntosExtra.
4.2.5. Polimorfismo
La idea es que una abstracción dada puede tener muy diferentes formas. El polimorfismo
permite tratar distintos tipos de objetos, como si fueran del mismo tipo. [Horton2003]
En Java el polimorfismo está siempre activo. Se resuelve en tiempo de ejecución según el
parámetro que tenga una función. Para ello el lenguaje proporciona el operador
55
Rafael Campillo Lorenzo.
TCM-SPC (2005-2006)
“Cavaleiro dos Céus”
Jogo de computador2D
“instanceof” que permite conocer el tipo de una referencia en tiempo de ejecución.
Se usa el polimorfismo en el Juego mediante la técnica de Casting o molde, consiguiendo
con ello que un objeto de la clase Sprite se pueda comportar en un momento dado como un
enemigo, un tiro, etc, simplemente amoldando su tipo al de la clase que interesa.
4.2.6. Eclipse 3.1
Eclipse es una plataforma de desarrollo extensible, basada en Java, de código abierto (Open
Source), diseñada para que se ejecute en múltiples sistemas operativos. Por si mismo es un
marco de trabajo con un conjunto de servicios para la construcción de entornos de
desarrollo de programación, con componentes plug-in; es decir, un contenedor sobre el que
montar herramientas de desarrollo para cualquier lenguaje sin más que desarrollar los
plugins correspondientes. Afortunadamente Eclipse viene con un conjunto estándar de
plug-ins entre los que se encuentra el Java Development Tool. [OTI2005]
Mientras la mayoría de los usuarios nos conformamos con usar Eclipse como un Integrated
Development Environment (IDE) para Java, sus ambiciones no acaban aquí. Eclipse
también incluye el Plug-in Development Environment (PDE), que es del mayor interés para
desarrolladores de software que quieran extender Eclipse.
La plataforma Eclipse está estructurada alrededor del concepto de Extension points.
Extension points son sitios en el sistema bien definidos donde otras herramientas (plug-ins)
pueden añadir funcionalidad. [OTI2005]
56
Rafael Campillo Lorenzo.
“Cavaleiro dos Céus”
TCM-SPC (2005-2006)
Jogo de computador2D
@9> &A
=
4.3.1. Gestión de eventos
Un objeto KeyListener es instanciado y registrado para recibir los eventos del teclado
KeyPressed(), KeyReleased().
Cuando se pulsa una tecla, el objeto que tenga el foco en
ese momento generará un evento Keypressed().
public void keyPressed(KeyEvent e){
jugador.keyPressed(e);}
public void keyReleased(KeyEvent e){
jugador.keyReleased(e);}
public void keyTyped(KeyEvent e){}
La clase Jogo2D recibirá todos los eventos de teclado.
Cuando ocurra un evento, la clase primero procesará las teclas que tengan que ver con el
juego en general como la tecla “escape” o similares.
Cuando se haya determinado que la tecla pulsada no interesa al juego en general, se le
pasan los datos de esa tecla Jugador para que actúe como crea oportuno. Esto ocurre
cuando se pulsan los cursores, la barra espaciadora o la tecla “B”.
public void keyPressed(KeyEvent e) {
if(e.getKeyCode()==KeyEvent.VK_ESCAPE)
System.exit(0);
else
jugador.keyPressed(e);
}
57
Rafael Campillo Lorenzo.
“Cavaleiro dos Céus”
TCM-SPC (2005-2006)
Jogo de computador2D
Se definirán los dos nuevos método en la clase Jugador, keyPressed(...) y
keyReleased(...),
que serán los encargados de recibir las notificaciones de que ha sido
pulsada / soltada una tecla.
4.3.2. Fotogramas
Como la animación es una característica que se desea que tengan todos los objetos del
juego, se añade esta funcionalidad a la clase Sprite.
nombresSprites,
es una matriz de nombres de gráficos que identifican la animación del
sprite.
El método setnombresSprite actualiza la variable nombresSprite, con todos los
nombres de las imágenes que se van a utilizar para la animación, y almacena como altura y
largura del sprite, la altura y la largura de la imagen mayor:
public void setnombresSprite(String [] nombres){
nombresSprites = nombres;
largura = 0;
altura = 0;
for (int i = 0; i < nombres.length; i++ ){
BufferedImage image = grafico.getGrafico(nombresSprites[i]);
largura = Math.max(largura,image.getHeight());
altura = Math.max(altura,image.getWidth());
}
}
Adicionalmente, el método actuar(), que es llamado cada vez que se realizan cálculos en
el bucle principal del juego, se encarga de incrementar el número de fotograma cada vez
que se actúa:
.
58
Rafael Campillo Lorenzo.
“Cavaleiro dos Céus”
TCM-SPC (2005-2006)
Jogo de computador2D
public void actuar(){
t++;
if (t % velocidadFrame == 0){
t=0;
frameActual = (frameActual + 1) % nombresSprites.length;
if(getColision()){
explosao.frameActual=(explosao.frameActual+1);
}
}
}
Se utiliza % spriteNames.length para asegurarse que el valor del frame actual siempre
esté entre 0 y el número de fotogramas – 1.
Además se mantiene dentro de la clase Sprite un contador de tiempos para actualizar el
fotograma sólo cuando este contador sea divisible por una cantidad llamada
velocidadFrame.
Con ello se consigue que la velocidad con la que se animan los sprites
sea independiente entre distintos sprites, e independiente de la velocidad del bucle
principal.
Hay que tener en cuenta que debido a la funcionalidad del método actuar() de la clase
sprite, las subclases de sprite no pueden sobrescribir el método sin más, sino que deben
llamar al método de la superclase antes de realizar sus propias acciones:
super.actuar();
4.3.3. Transformaciones Afines
Se usan las transformaciones afines en los métodos paint() de las clases Enemigo, y
tirosEnemigo
porque es necesario rotar los sprites conforme la trayectoria y dirección en
la que se desplazan.
59
Rafael Campillo Lorenzo.
“Cavaleiro dos Céus”
TCM-SPC (2005-2006)
Jogo de computador2D
Después de realizar una transformación afín, se pinta el sprite y a continuación se deshace
la transformación para que no afecte a los ejes de referencia y el sistema de coordenadas de
manera global y sólo al sprite en cuestión. Para deshacer la rotación se aplica la
transformación con el ángulo inverso.
AffineTransform mov;
mov=AffineTransform.getRotateInstance(angulo,getPosX(),getPosY());
g.transform(mov);
super.paint(g);
mov=AffineTransform.getRotateInstance(-angulo,getPosX(),getPosY());
g.transform(mov);
4.3.4. Carga de imágenes
Los gráficos que se usen en el juego serán imágenes externas que se irán cargando según se
vayan necesitando
Para poder tener transparencias sin complicaciones se usarán imágenes en formato .GIF o
.PNG.
Para cargar la imagen se utliza la clase ImageIO.
Las imágenes a cargar están en un directorio llamado “res” (resources) que cuelga del
directorio
del
proyecto.
(Un
ejemplo
podría
ser
este:
C:\Documents
and
Settings\Administrador\workspace\Jogo2D\res).
Se encapsula todo en una jerarquía de clases. Las clases encargadas de la carga de
imágenes son la clase GraficosCache y su superclase, RecursosCache. En ella existen
tres métodos diferenciados: cargarRecurso(URL url), getGrafico(String nombre) y
createCompatible(int width,int height,int transparency).
La clase es sencilla
y su única motivación es la de dar gráficos a quien los necesite. La clase precisará de un
mapa de sprites y el método para cargar una imagen en memoria.
60
Rafael Campillo Lorenzo.
“Cavaleiro dos Céus”
TCM-SPC (2005-2006)
getGrafico(String nombre),
Jogo de computador2D
este método recibirá como parámetro de entrada un
nombre de sprite que se necesite y devolverá la imagen, cargándola si es necesario. Puesto
que puede haber muchas imágenes, la rutina tendrá que recordar qué sprites están cargados
y cuáles no. Para ello nada mejor que una HashMap que asocie el nombre de cada sprite
con su imagen en memoria.
getClass().getClassLoader().getResource(...),
permite
obtener
una
URL
apuntando a un subdirectorio relativo al sitio del cual fue cargada la clase.
4.3.5. Imágenes Compatibles
Una imagen compatible, es una imagen en memoria que tiene las mismas características (o
al menos muy similares) al modo de vídeo nativo que se está mostrando en ese momento
(en términos de bits por píxel, transparencia, etc.).
Las imágenes compatibles son mucho más rápidas de dibujar que cualquier otro formato.
Antes de usarlas, lo que se hacía era utilizar el formato que a ImageIO le apeteciese
devolver. Se puede optimizar esto de la siguiente forma:
Se lee la imagen de disco utilizando ImageIO.
Se crea una imagen compatible del mismo tamaño que la imagen leída.
Se pinta la imagen recién cargada encima de la imagen compatible.
De esta forma se obtiene una “versión compatible” de una imagen situada en el disco:
public BufferedImage createCompatible(int width,int height,int transparency){
GraphicsConfiguration gc;
gc=GraphicsEnvironment.getLocalGraphicsEnvironment().getDefaultScreenDevice().get
DefaultConfiguration();
BufferedImagecompatible=gc.createCompatibleImage(width,height,transparency);
return compatible;
}
61
Rafael Campillo Lorenzo.
TCM-SPC (2005-2006)
“Cavaleiro dos Céus”
Jogo de computador2D
4.3.6. Doble Buffering
En primer lugar, se decide qué ventana o componente es la que presentará este tipo de
comportamiento. Se ha de escoger aquel componente sobre el que se va a pintar.
Se llama al método createBufferStrategy(n) de esa ventana, pasando como parámetro
el número de buffers que se desean tener. Se crean 2 búferes.
Se utliza el método getBufferStrategy() de la ventana para obtener un objeto de tipo
BufferStrategy,
que representa básicamente una ristra de buffers de memoria, tantos
como indique el parámetro que se pasó al método createBufferStrategy().
Para poder pintar encima del buffer de dibujo, se llama al método getDrawGraphics() del
objeto BufferStrategy obtenido anteriormente.
Cuando se termine de pintar, se llama al método show() del objeto BufferStrategy para
indicar que el buffer está listo y que se quiere mostrar el siguiente buffer.
...
private BufferStrategy strategy;
...
createBufferStrategy(2);
strategy = getBufferStrategy();
...
g.drawString(“…”, x, y);
strategy.show();
...
62
Rafael Campillo Lorenzo.
TCM-SPC (2005-2006)
“Cavaleiro dos Céus”
Jogo de computador2D
4.3.7. Colisiones
Habrá una colisión cuando los rectángulos que encierran cada sprite se intersecten.
Figura 7- Intersección de los rectángulos de dos sprites.
Esta comprobación habrá que hacerla para todas las posibles parejas de sprites, y además
habrá que hacerla para cada sprite con el jugador. Puesto que ello involucra manejar el
vector global de sprites, se lleva a cabo en la clase principal, Jogo2D.
La clase Rectangle de Java incorpora el método intersects() que permite comprobar si
un rectángulo intersecta con otro. Como se necesita saber los rectángulos que engloban
cada sprite, se añade un método getRectangulo() en la clase Sprite que ya devuelva el
objeto Rectangle construido, con las dimensiones y coordenadas del sprite.
public Rectangle getRectangulo(){
return new Rectangle((int)posX,(int)posY,(int)largura,(int)altura);
}
Cuando se detecta una colisión se notifica a cada sprite (mediante polimorfismo) que se ha
producido una colisión con otro sprite, siendo estos los que deciden qué hacer en
consecuencia. Esto significa que aparece un nuevo método en la clase Sprite llamado
colision().
Por defecto este método no hace nada, siendo las subclases las responsables
de sobreescribirlo como consideren oportuno. La clase Enemigo se actúa cuando la colisión
63
Rafael Campillo Lorenzo.
“Cavaleiro dos Céus”
TCM-SPC (2005-2006)
Jogo de computador2D
es contra un objeto de tipo Tiro, o Bomba, y en tal caso se marca como eliminado el objeto
Enemigo.
G
En la clase principal se crea el método que chequea las colisiones:
public void chequearColisiones() {
Rectangle rectanguloJugador = jugador.getRectangulo();
for (int i = 0; i < vectorSprites.size(); i++) {
Sprite s1 = (Sprite)vectorSprites.get(i);
Rectangle r1 = s1.getRectangulo();
if (r1.intersects(rectanguloJugador)) {
jugador.colision(s1);
s1.colision(jugador);
}
for
(int
j
=
i+1;
j
<
vectorSprites.size();
j++){
Sprite s2 = (Sprite)vectorSprites.get(j);
Rectangle r2 = s2.getRectangulo();
if (r1.intersects(r2)) {
s1.colision(s2);
s2.colision(s1);
}
}
}
}
@9@9
< '
Como la mayoría de los lenguajes orientados a objetos, Java incluye un conjunto de
librerías de clase que proveen de tipos de datos básicos, capacidades de entradas y salidas al
sistema y otras funciones de utilidad.
Las clases básicas forman parte del JDK (Java Development Kit). Al ser estas librerías
escritas en Java, son portables entre plataformas al igual que lo son las aplicaciones escritas
en Java. Algunas librerías importantes usadas son:
64
Rafael Campillo Lorenzo.
TCM-SPC (2005-2006)
“Cavaleiro dos Céus”
Jogo de computador2D
4.4.1. javax.swing.JFrame
java.lang.Object
java.awt.Component
java.awt.Container
java.awt.Window
java.awt.Frame
javax.swing.JFrame
El paquete Swing es parte de la JFC (Java Foundation Classes) en la plataforma Java.
La JFC provee facilidades para ayudar a la gente a construir GUIs. Swing abarca
componentes como botones, tablas, marcos, etc...
4.4.2 java.*.BufferedImage
java.lang.Object
java.awt.Image
java.awt.image.BufferedImage
La subclase BufferedImage describe una imagen con un buffer de datos de imágenes
accesibles. Un BufferedImage está comprendido por un Color Model y un raste de cada
datosde imagen.
4.4.3. java.*.BufferStrategy
java.lang.Object
java.awt.image.BufferStrategy
65
Rafael Campillo Lorenzo.
TCM-SPC (2005-2006)
“Cavaleiro dos Céus”
Jogo de computador2D
Usamos esta librería para usar la técnica del doble buffering. Las limitaciones de Hardware
y Software determinan cómo un Buffer Strategy puede ser implementado. Un buffer no
deja de ser un área de memoria contigua, tanto en una memoria de un dispositivo de vídeo
como en un sistema de memoria.
4.4.4. java.util.HashMap
java.lang.Object
java.util.AbstractMap
java.util.HashMap
4.4.5. java.awt.event.KeyEvent
java.lang.Object
java.util.EventObject
java.awt.AWTEvent
java.awt.event.ComponentEvent
java.awt.event.InputEvent
java.awt.event.KeyEvent
Un evento que indica cuando una pulsación de tecla ha ocurrido en un componente.
4.4.6. java.awt.Graphics2D
java.lang.Object
java.awt.Graphics
java.awt.Graphics2D
66
Rafael Campillo Lorenzo.
TCM-SPC (2005-2006)
“Cavaleiro dos Céus”
Jogo de computador2D
El API 2D de Java presenta java.awt.Graphics2D, un tipo de objeto Graphics. Graphics2D
desciende de la clase Graphics para proporcionar acceso a las características avanzadas de
renderizado del API 2D de Java.
67
Rafael Campillo Lorenzo.
“Cavaleiro dos Céus”
TCM-SPC (2005-2006)
-9
Jogo de computador2D
"
& 6 D;
6
-9,9 "
Para la creación de los sprites de los aviones se ha utilizado un programa generador de
aviones de la segunda guerra mundial codificado en javar [Peralta2005].
WW2plane:
es una Clase en Java 2D para el diseño gráfico de aviones de la Segunda Guerra
Mundial. Sólo tiene la posibilidad de diseñar cazas de motor de una única ala. También es
posible el diseño de bombarderos.
El diseño de los aviones se efectúa recurriendo a la API gráfica de Java de tal modo que, a
través de llamadas a métodos, un usuario de la clase WW2plane podrá construir aviones a su
gusto.
Todas las características de los aviones están completamente parametrizadas con lo que se
puede diseñar cualquier tipo de avión con las características que se deseen, hasta
inventados. [Peralta2005]
Figura 8 - Logotipo de WW2plane
Una vez que se ha decidido qué tipos de aviones son los se quieren, y son diseñados con el
programa, se hacen capturas de pantalla mediante el comando ALT + PRINT SCREEN, que
68
Rafael Campillo Lorenzo.
TCM-SPC (2005-2006)
“Cavaleiro dos Céus”
Jogo de computador2D
en vez de capturar toda la pantalla, captura sólo la ventana activa, o sea la ventana del
applet con las vista de nuestro avión.
Se abre un nuevo archivo con el Adobe Photoshop CS2 y se pega la captura de pantalla. A
continuación se crearon 2 macros que permitirán recortar los aviones, quitar el fondo
blanco para dejarlo transparente, y reducir el tamaño del avión un 75%. Las 2 macros
creadas son separaAviao y reduz75. A partir de ahí sólo restaría guardarlas en formato
PNG, para que se mantengan todas las características de las capas, y también la
transparencia.
Figura 9 - Macros creadas para Photoshop CS2
69
Rafael Campillo Lorenzo.
TCM-SPC (2005-2006)
“Cavaleiro dos Céus”
Jogo de computador2D
Se ha diseñando un avión split de la RAF (Royal Air Force) y para los enemigos aviones
creados aleatoriamente. Entre ellos se distinguen claramente aviones con emblemas
alemanes o japoneses; todo ello creado mediante la manipulación de parámetros de la clase
WW2plane.
Figura 10 - Secuencia sprites de un avión japonés
Figura 11 - Secuencia de sprites de un avión alemán
También han sido creados con el Photoshop CS2 otros sprites como las bolas que aparecen
aleatoriamente al ser destruidos algunos aviones y que contienen un incremento de puntos
extra si son alcanzadas por el jugador.
Figura 12 - Secuencia de sprites de puntosExtra
70
Rafael Campillo Lorenzo.
TCM-SPC (2005-2006)
“Cavaleiro dos Céus”
Jogo de computador2D
-9 9 1
Las explosiones han sido diseñadas en el Photoshop CS2 pintando cada frame de la
explosión con la herramienta “brush”, y con el modo “disolve”.
Figura 13 - Secuencia de sprites de una explosión
-9>9
Para la creación de los escenarios se ha optado por dar un aire realista a las texturas de los
fondos. Para ello se han ido capturando imágenes sucesivas de distintas zonas del globo
terráqueo con el GoogleEarth, un programa que permite visionar cualquier parte del planeta
vía satélite a distintas resoluciones dependiendo de la altura. Las imágenes visionadas no
son en tiempo real. GoogleEarth tiene una opción que permite guardar las imágenes con
distintas resoluciones.
A continuación se pasan al Photoshop CS2 para poder manipularlas. La manipulación
consiste en conseguir que todas tengan la misma resolución y cortarlas para por el sitio
exacto para que no se distinga la frontera entre dos texturas consecutivas a la hora de
desplazar los escenarios.
Para ello se crea una canvas de 1024 píxels de resolución de anchura y con una longitud
igual al total de las imágenes capturadas. Se pone cada imagen en capas distintas y jugando
con las máscaras en las fronteras de las imágenes para suavizar el corte, se consigue una
imagen general del escenario de una fase.
A continuación se seleccionan y copian zonas del escenario para crear texturas
independientes con el tamaño y resolución deseado: 1024 x 768 píxels. Se usa la
71
Rafael Campillo Lorenzo.
“Cavaleiro dos Céus”
TCM-SPC (2005-2006)
Jogo de computador2D
herramienta crop del Photoshop para obtener el área a copiar en un nuevo fichero, con las
dimensiones exactas.
Para finalizar se guardan todas las texturas en formato PNG.
-9@9
(
Al principio de cada una de las fases hay una pantalla de presentación con el nombre del
juego y la fase. En medio aparece un avión que previamente ha sido procesado con el
Photoshop y que hemos obtenido al igual que los sprites, haciendo una captura de pantalla
del avión generado por el programa WW2plane.
El resto de la pantalla es una textura creada con el Photoshop. Por tanto se han creado para
el juego dos texturas, una simulando el efecto de la lluvia por la noche y la otra un efecto de
niebla.
Para el efecto de noche nublada se escogen dos colores (negro y azul oscuro) como
foreground y background de la imagen. A continuación se aplica un filtro: Filter /
Render /Clouds,
que de forma automática y aleatoria mezcla los dos colores escogidos
creando nubes. Este proceso se repite para crear la textura con efecto de niebla, pero
escogiendo como colores un gris medio y blanco.
A continuación se crean dos nuevas capas en las que se pintan unas gotas de agua con la
herramienta brush.
Esas gotas se seleccionan y se definen como patrón: Edit / Define Pattern, con lo que
se tienen dos patrones.
Ahora se rellena una nueva capa con el patrón de la lluvia y se le aplica un efecto blur para
alargar las gotas de agua y cambiar su ángulo de inclinación. Filter / Blur / Motion
Blur.
Repetimos el proceso para el otro patrón de lluvia definido, y con la mezcla de ambos tipos
de gotas se obtiene un efecto de lluvia realista para la textura.
72
Rafael Campillo Lorenzo.
TCM-SPC (2005-2006)
59
“Cavaleiro dos Céus”
Jogo de computador2D
&
Los objetivos planteados al inicio del proyecto están sobradamente conseguidos.
Se ha logrado construir un juego en dos dimensiones tipo arcade, en el que el lenguaje
utilizado y aprendido para su creación ha sido el lenguaje Java.
En éste, las imágenes se tratan correctamente y se trasladan por la pantalla. Ha sido
necesario un estudio pormenorizado del tratamiento de las imágenes por el lenguaje Java, y
de las propiedades de distintos formatos de imagen, como las transparencias, para utilizar
las más adecuadas. Así como la utilización de programas especializados en el tratamiento
de imágenes como Photoshop CS2, para la creación de la parte gráfica del juego.
Además se ha conseguido un efecto correcto de desplazamiento de los escenarios pudiendo
cargar todas las texturas distintas que se crean oportunas y dando pie esto a tener distintas
fases por las que evolucione el juego.
Se gestionan distintos eventos como la pulsación de teclas, que permitirán desplazar por la
pantalla el avión del jugador, generar nuevos sprites como los disparos y bombas, o escapar
del juego pulsando la tecla de escape.
Se consigue animar distintos sprites mediante la sucesión de frames o fotogramas.
Se profundiza en conocimientos de computación gráfica en 2 dimensiones utilizando la
Graphics2D de java (transformaciones afines…)
Y en definitiva, se ha profundizado en la filosofía de creación de un juego de computador
en dos dimensiones, adquiriendo unas nociones y metodologías para afrontar futuros
problemas y retos de este tipo y sucesivos proyectos de creación de juegos en 2D. También
adquirimos una base fundamental de conocimientos para dar el salto a la programación de
juegos en 3D.
73
Rafael Campillo Lorenzo.
TCM-SPC (2005-2006)
“Cavaleiro dos Céus”
Jogo de computador2D
Por lo tanto el juego cumple unos objetivos mínimos de jugabilidad, pero puede ser
mejorado y ampliado.
Se puede depurar mucho más el código de tal forma que sea más eficiente y eso se refleje a
la hora de jugar, ya que se nota el peso de las imágenes si se muestran demasiados sprites
en la pantalla.
Además las trayectorias de los aviones están limitadas y se puede ampliar a muchas más sin
demasiada complicación, creando patrones de trayectorias no aleatorios que embellezcan el
juego, creando nuevos tipos de trayectorias, persecuciones, etc.
Dotar al juego de una mayor inteligencia artificial de la que posee actualmente, con
persecuciones por parte de los aviones enemigos al avión del jugador y evasiones de éste,
disparos de los aviones enemigos cuando el avión del jugador estuviese en su ángulo de
tiro, etc.
Crear escenarios originales con programas de diseño que dotasen de otra visión al juego.
Crear un guión y una historia con unos objetivos. Misiones que hiciesen más interesante
jugar, dando un sentido y una motivación extra al tener que cumplir estas misiones y al
poder situarse dentro de un contexto, ya sea real o imaginado.
Para mejorarlo se pueden crear “monstruos” finales, donde al final de cada fase se luchase
contra un enemigo más difícil. Podrían ser simplemente aviones más grandes y que en lugar
de explotar al recibir un único disparo del jugador, tuviese un nivel de vida que fuese
descendiendo conforme recibiese impactos de tiros. Además podría disparar el mismo tipo
de bomas que dispara el jugador. En definitiva consistiría en añadir un nivel más alto de
dificultad al juego.
74
Rafael Campillo Lorenzo.
TCM-SPC (2005-2006)
“Cavaleiro dos Céus”
Jogo de computador2D
Se podrían crear nuevos objetos similares a los objetos de PuntosExtra, que
proporcionasen vida al jugador si éste los interceptase.
Se podría simular una nueva dimensión creando distintos niveles de altura, simplemente
haciendo los sprites más grandes cuando subiesen de altura y por consiguiente más pequeño
el fondo puesto que nos alejamos de él, y más pequeños cuando bajasen y más grande el
fondo del escenario.
Se podría crear una pantalla de presentación de cada nivel con una animación presentando
la historia y misión a conseguir en la siguiente fase.
También se podrían crear objetos que se desplazasen a la misma velocidad que el escenario
para simular que están fijos en la tierra, como cañones antiaéreos, tanques, etc. Además no
sería difícil hacer que rotasen hacia el avión del jugador y siempre le disparasen a hacia él.
Incluso también se podría animar el fondo del escenario cuando se desplaza.
Por lo tanto se observa cómo las mejoras del juego son muchas y que el juego no es
perfecto, pero no era objetivo de este proyecto crear un juego profesional con muchos
niveles, sprites y gráficos, sino crear una base sólida y adquirir los conocimientos
suficientes para poder ampliar esa base sin demasiada complicación.
75
Rafael Campillo Lorenzo.
“Cavaleiro dos Céus”
TCM-SPC (2005-2006)
E9
7
Jogo de computador2D
7
El proyecto consiste en analizar y estudiar técnicas y algoritmos que lleven a la realización
de un juego de computador en dos dimensiones.
Como parte práctica que complemente el trabajo de investigación teórico, se ha
desarrollado un juego de computador, recurriendo a la tecnología orientada a objetos, y
computación gráfica en dos dimensiones; utilizando el lenguaje Java como lenguaje de
desarrollo.
Los objetivos marcados al inicio fueron:
La traslación de imágenes por la pantalla
La visualización de sprites.
La gestión de eventos.
Y la programación multihilo para poder hacer varias acciones en paralelo e
independientes unas de otras.
Todos los objetivos se han cumplido. Se ha conseguido que las distintas imágenes que
forman el escenario se desplacen en vertical por la pantalla para conseguir la sensación de
avance por parte del avión del jugador. Además los distintos sprites (avión del jugador,
aviones enemigos, bombas, etc) también se desplazan por la pantalla siguiendo distintas
trayectorias rectilíneas o curvilíneas aleatorias, o respondiendo a eventos generados por la
pulsación de teclas, como es el caso del avión del jugador.
También se consigue visualizar los sprites y animarlos. Para ello se dispone de una Hasmap
que permite guardar pares nombre-imagen, o clave-valor, y luego recuperar esas imágenes
utilizando el nombre.
Por tanto mediante un índice que indica cuál es el fotograma actual se va recorriendo el
vector de nombres y actualizando el índice a la hora de pintar.
76
Rafael Campillo Lorenzo.
TCM-SPC (2005-2006)
“Cavaleiro dos Céus”
Jogo de computador2D
Además se realiza la gestión de eventos de pulsación de teclas por parte del jugador.
Se ha utilizado Java2D como lenguaje de desarrollo del juego por ser un Lenguaje
Orientado a Objetos, que permite abstracción, encapsulación, herencia y polimorfismo; por
su sencillez y potencia, y porque permite crear grandes aplicaciones que corran bajo
cualquier sistema operativo, independientemente de la máquina en que se ejecuten, es decir,
por su portabilidad.
He acertado con la elección del proyecto puesto que compaginaba de alguna forma la base
formativa que ya traía del curso que estoy estudiando en España, con todo lo que iba a
aprender este año; Realimentando y fortaleciendo conocimientos de unas asignaturas con
otras. Por tanto la realización de este proyecto ayuda de forma considerable a asentar los
conocimientos adquiridos y a ver el curso de multimedia de una forma global.
El descubrimiento del curso de TCM, y la posibilidad de realizar este proyecto ha abierto
un nuevo universo con infinitas posibilidades ante mis ojos, donde poder enfocar de alguna
manera mi futuro profesional, a pesar de no tener mucho que ver con lo que estudio en
España
Tener un resultado tan gráfico y visual del trabajo mientras uno lo va desarrollando es una
motivación extra para avanzar, y a pesar de la falta de tiempo para optimizar más aun el
juego, han sido muchas las ideas que se me iban ocurriendo, conforme se adquirían
conocimientos, para mejorarlo y darle un aspecto más espectacular.
Por lo tanto el juego se puede mejorar sin mucho esfuerzo sobre todo en su parte gráfica ya
que la base de programada es bastante sólida y permite agregar elementos sin dificultad.
Creación de escenarios propios, de nuevos objetos tanto voladores como fijos en tierra,
distintos niveles de altura para que los aviones suban y bajen, incremento de fases del juego
con un guión. Etc.
77
Rafael Campillo Lorenzo.
TCM-SPC (2005-2006)
“Cavaleiro dos Céus”
Jogo de computador2D
Considero que ha sido una experiencia muy gratificante el ir afrontando problemas que
surgían durante la creación del juego, y alcanzar la solución a los mismos. Se aprende con
ello a trabajar organizadamente y cumpliendo unos plazos, a trabajar en equipo con tu
orientador o profesores que hayan ayudado, a investigar en libros, en internet, pero
sobretodo, se aprende a conocer el potencial que tiene uno mismo y hasta dónde puede
llegar.
78
Rafael Campillo Lorenzo.
“Cavaleiro dos Céus”
TCM-SPC (2005-2006)
.9 B B
6
Jogo de computador2D
;8
[Knudsen1999] Jonathan Knudsen, Java 2D Graphics, O’Reilly.
ISBN: 1-56592-484-3
[Brackeen2004] David Brackeen With Bret Brackeen and Laurence Vanhelsuwé,
Developing Games in Java , NRG. ISBN: 1-5927-3005-1
[Bourg2004] David M. Bourg & Glenn Seemann, AI for Game Developers, O’Reilly.
ISBN: 0-596-00555-5
[McShaffry2003] Mike McShaffry, Game Coding Complete, Paraglyph press.
ISBN: 1-932111-75-1
[Coelho2003] Pedro Coelho, Programaçao en JAVA 2 (curso completo), FCA
ISBN: 972-722-348-6
[Flanagan2005] David Flanagan, JAVA in a nutshell, O’Reilly.
ISBN: 0-596-00283-1
[Martins2006] José Martins, CG2D_Java2D, 2006-ISMAI
[Horton2003] Ivor Horton, Beginning Java 2,SDK 1.4 Edition , Wrox Press
ISBN: 0764543652
[OTI2005] OTI Employee, Eclipse – Platform Plug-in Developer Guide
ISBN: I20050627-1435
79
Rafael Campillo Lorenzo.
TCM-SPC (2005-2006)
“Cavaleiro dos Céus”
Jogo de computador2D
[Peralta2005] Luís Miguel Guerra Figueira Peralta, WW2plane. Classe JAVA2D para
desenho de aviões da Segunda Grande Guerra.
[www_01] http://es.wikipedia.org/wiki/Videojuego
[www_02] http://es.wikipedia.org/wiki/Arcade
[www_03] http://es.wikipedia.org/wiki/Sprite_(videojuegos)
[www_04] http://es.wikipedia.org/wiki/Coordenadas_polares
[www_05] http://www.programacion.com/java/tutorial/ags_j2me/8/
[www_06] http://www.docjar.com/docs/api/java/util/HashMap.html
[www_07]
http://www.programacion.com/blogs/80_tecnicas_de_programacion/categories/200_de
sarrollo_de_juegos.html
[www_08] http://www3.uji.es/~vcholvi/teaching/java/cap.05.1/Cap.05.1.html
80
Rafael Campillo Lorenzo.
“Cavaleiro dos Céus”
TCM-SPC (2005-2006)
Jogo de computador2D
/9 87
Animación, 9, 11, 16, 19, 23, 24, 25, 44,
75
Avión, 15, 45, 46, 47, 68, 69, 70, 72, 73,
75, 76, 83, 84, 85
Buffering, 21, 64
Clases, 20, 36, 37, 38, 39, 42, 43, 50, 54,
55, 64
Imagen, 10, 16, 18, 19, 20, 21, 22, 24, 25,
27, 28, 29, 38, 41, 42, 44, 49, 50, 58,
60, 61, 65, 71, 72, 73, 76
Java, 51, 52, 53, 56, 79, Véase
Juego, 2, 9, 10, 11, 13, 15, 36, 37, 40, 42,
44, 50, 51, 68
Jugador, 13, 14, 15, 20, 36, 37, 38, 40,
Colisiones, 4, 27, 40, 44, 51, 63, 64
41, 42, 44, 45, 46, 47, 51, 55, 57, 63,
Enemigo, 15, 44, 46, 47, 56, 74, 85
64, 70, 73, 74, 75, 76, 77, 83, 84, 85
Evasión, 32, 33, 34
Persecución, 32, 33, 34
Eventos, 9, 11, 25, 26, 41, 49, 57, 73, 76,
Photoshop, 69, 70, 71, 72, 73
77
Fotogramas, 24, 44, 51, 73
Gráfica, 9, 11, 16, 22, 68, 73, 77
Scroll, 10, 26, 27, 37, 38
Sprites, 9, 11, 15, 16, 20, 27, 28, 29, 38,
40, 41, 42, 43, 44, 45, 49, 51, 68, 70,
71, 72, 73, 74, 75
81
Rafael Campillo Lorenzo.
“Cavaleiro dos Céus”
TCM-SPC (2005-2006)
Jogo de computador2D
,49 7 F
,49,9
1 0
10.1.1. Instalación
El juego “Cavaleiro dos Céus” se proporciona en un CD con lo que se puede ejecutar desde
la unidad de CD-ROM, o copiar la carpeta /deploy al disco duro del computador, que es
lo más aconsejable, ya que ejecutar la aplicación desde un dispositivo periférico puede
relantizar su velocidad.
A continuación basta con ejecutar el fichero de procesamiento por lotes cavaleiro.bat y
comenzaría el juego. Es importante ejecutar dicho archivo dentro del directorio en el que se
encuentra puesto que en él se encuentra la carpeta /deploy/res donde están todas las
imágenes, texturas, sonidos y en definitiva recursos utilizados por la aplicación, y también
todos los ficheros *.class. Se tienen tres ficheros ejecutables distintos con las siguientes
resoluciones: 800x600px, 1024x768 y 1280x800. Si se desease ver el juego en pantalla
completa, tendrían que coincidir la resolución del archivo ejecutable con la resolución de la
pantalla.
Cada
ejecutable
se
encuentra
en
la
carpeta:
/cavaleiro800x600,
/cavaleiro1024x768, /cavaleiro1280x800.
Si no se dispusiese del fichero autoejecutable, habría que tener en cuenta que Java es un
lenguaje interpretado. Por lo tanto un requisito imprescindible para la ejecución del juego
“Cavaleiro dos Ceus” sería tener instalada la Máquina Virtual de Java para interpretar los
BytesCodes, que como ya se ha comentado es una representación intermedia.
El programa compilado se podría interpretar desde cualquier editor o entorno de trabajo
preparado para ello como el Eclipse 3.1, o también desde consola vía comandos. Si no se
82
Rafael Campillo Lorenzo.
“Cavaleiro dos Céus”
TCM-SPC (2005-2006)
Jogo de computador2D
hubiese compilado anteriormente el fichero principal (el que contiene la función Main())
habría que hacerlo antes de interpretarlo.
Para acceder a las herramientas proporcionadas por el JSDK, se debe acceder al directorio
/JavaHome/BIN.
Una forma de hacer dichas herramientas accesibles desde cualquier
directorio es insertándolo dentro del PATH del sistema, ya que esa variable especifica las
rutas alternativas en las que el intérprete de comandos debe buscar una aplicación cuando
ésta sea ejecutada desde de línea de comandos:
SET PATH=%PATH%;JavaHome\bin;
El comando para compilar la aplicación en modo consola sería:
Javac [options] [NombreFichero.java] [argfiles]
Por defecto el compilador generará cada fichero .class en el mismo directorio del fichero
de su código fuente correspondiente.
Para interpretar desde la consola habría que usar la siguiente sintaxis:
Java [options] [NombreFicher]
10.1.2. Comandos para el manejo del juego
El juego comienza con la presentación del mismo, es decir, título del juego y fase en la que
nos encontramos, y a continuación se presenta la pantalla inicial con aviones enemigos en
distintas trayectorias disparando, y con el avión del jugador centrado en la parte inferior de
la pantalla. Las teclas para manejar el juego son las siguientes:
ESC: pulsando esta tecla se permite abortar la aplicación y abandonar el juego antes de su
finalización. También es necesario pulsarla a la finalización del juego.
83
Rafael Campillo Lorenzo.
TCM-SPC (2005-2006)
“Cavaleiro dos Céus”
Jogo de computador2D
Cursores: Permiten desplazar el avión por la pantalla en las cuatro direcciones que apuntan
las flechas. La combinación de dos cursores a la vez, permite desplazar el avión del jugador
trazando una diagonal con lo que el número de direcciones permitidas para el jugador pasa
a ser 8 (norte, noreste, este, sureste, sur, suroeste, oeste y noroeste).
Espacio: Pulsando la barra espaciadora dispara el avión del jugador.
B: Pulsando la tecla “B” el avión del jugador dispara 8 bombas en las 8 direcciones: norte,
noreste, este, sureste, sur, suroeste, oeste y noroeste. El jugador dispondrá de un número
limitado de bombas para toda la partida.
10.1.3. Reglas del juego
El Barón Rojo es un mito que inspira cierto romanticismo, y en nuestro caso el nombre del
juego, puesto que también era conocido como “El Caballero de los Cielos”. Su historia es la
historia de un piloto invencible, amable con sus enemigos y que seguía un estricto código
de honor, todo un caballero andante de los cielos europeos. Pero es también la historia del
fin de una era, la era de las individualidades, de la guerra caballerosa. Con la muerte del
Barón Rojo se entró de lleno en la nueva era de guerra total, de atrocidades y de fanatismo,
la guerra de esta era la gana quien tiene más material, más masa, más poder de destrucción,
más fanáticos…
Bajo estas condiciones recuperamos ese aire romántico para la segunda guerra mundial
puesto que el jugador tendrá que enfrentarse solo, a un gran número de aviones enemigos
El juego está compuesto por dos fases. La primera fase se llama “Mission Taiwan”, y si se
finalizase esta fase satisfactoriamente se pasaría a la segunda y definitiva: “Mission
Berlín”.
84
Rafael Campillo Lorenzo.
TCM-SPC (2005-2006)
“Cavaleiro dos Céus”
Jogo de computador2D
El jugador manejará un avión cazabombardero “Spitfire” característico de la Segunda
Guerra Mundial, y que pertenecerá a la RAF (Royal Air Force) Británica, y por
consiguiente al eje aliado durante la guerra.
Mission Taiwan: en esta primera fase se hace una incursión en la costa de Taiwan, donde el
Spitfire del usuario se tendrá que enfrentar a varios escuadrones de aviones enemigos
pertenecientes a distintos ejércitos. Los aviones enemigos sólo disparan con ametralladoras
características de ese tipo de aviones, mientras que el usuario dispondrá de dos tipos
distintos de armamentos: misiles y bombas. Los misiles sólo se disparan en una única
dirección norte al “pulsar la barra espaciadora”, y las bombas en todas las direcciones (8) al
pulsar la tecla “b”.
Esas serán las armas con las que contará el jugador para derrotar los escuadrones enemigos.
Por cada avión derribado el jugador va obteniendo 20 puntos. Algunos aviones al ser
derribados se convierten en una bola que se mueve libremente por la pantalla. La
intercepción de esa bola por el jugador supondrá un incremento de 100 puntos en su
casillero.
Por otro lado cada vez que el avión del jugador sea alcanzado con algún proyectil enemigo,
sufrirá daños con lo que su nivel de vida irá bajando. Si el nivel de vida se pone a 0, el
jugador muere y acaba la partida.
Si el avión del jugador se colisiona con algún avión enemigo, también explota acabándose
la partida.
Para pasar a la siguiente fase hay que eliminar todo escuadrón enemigo o aguantar sin ser
derribado hasta el último escenario de la fase.
85
Rafael Campillo Lorenzo.
TCM-SPC (2005-2006)
“Cavaleiro dos Céus”
Jogo de computador2D
Mission Berlin: La siguiente fase tendría las mismas condiciones que la anterior cambiando
el escenario. El campo de batalla se aleja de la costa para desarrollarse en el interior de
Europa.
Si se eliminan todos los escuadrones se habrá llegado al final del juego con una cantidad de
puntos que dependerá de los aviones enemigos derribados durante el transcurso de las dos
fases.
86
Rafael Campillo Lorenzo.
“Cavaleiro dos Céus”
TCM-SPC (2005-2006)
,49 9
1
0 !
Jogo de computador2D
# 1
=
9
87
Rafael Campillo Lorenzo.
TCM-SPC (2005-2006)
“Cavaleiro dos Céus”
Jogo de computador2D
88
Rafael Campillo Lorenzo.
TCM-SPC (2005-2006)
“Cavaleiro dos Céus”
Jogo de computador2D
89