˘ ˇˆ - la caja de pandora de un camaleón · mi orientador y yo creímos oportuno compaginar los...

89
!"# $% &’$% ( )* +,-./- 0123 *244-*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

Upload: dinhkien

Post on 09-Sep-2018

214 views

Category:

Documents


0 download

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. “Cavaleiro dos Céus”

TCM-SPC (2005-2006) Jogo de computador2D

2

� �����

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.

Rafael Campillo Lorenzo. “Cavaleiro dos Céus”

TCM-SPC (2005-2006) Jogo de computador2D

3

�6�������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…

Rafael Campillo Lorenzo. “Cavaleiro dos Céus”

TCM-SPC (2005-2006) Jogo de computador2D

4

�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

Rafael Campillo Lorenzo. “Cavaleiro dos Céus”

TCM-SPC (2005-2006) Jogo de computador2D

5

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

Rafael Campillo Lorenzo. “Cavaleiro dos Céus”

TCM-SPC (2005-2006) Jogo de computador2D

6

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

Rafael Campillo Lorenzo. “Cavaleiro dos Céus”

TCM-SPC (2005-2006) Jogo de computador2D

7

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

Rafael Campillo Lorenzo. “Cavaleiro dos Céus”

TCM-SPC (2005-2006) Jogo de computador2D

8

87�������� �&����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

Rafael Campillo Lorenzo. “Cavaleiro dos Céus”

TCM-SPC (2005-2006) Jogo de computador2D

9

,9��7&� ���: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

Rafael Campillo Lorenzo. “Cavaleiro dos Céus”

TCM-SPC (2005-2006) Jogo de computador2D

10

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

Rafael Campillo Lorenzo. “Cavaleiro dos Céus”

TCM-SPC (2005-2006) Jogo de computador2D

11

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

Rafael Campillo Lorenzo. “Cavaleiro dos Céus”

TCM-SPC (2005-2006) Jogo de computador2D

12

,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.

Rafael Campillo Lorenzo. “Cavaleiro dos Céus”

TCM-SPC (2005-2006) Jogo de computador2D

13

�9���&�������7������7&��

�9,9�?���������������2����=�������������

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.

Rafael Campillo Lorenzo. “Cavaleiro dos Céus”

TCM-SPC (2005-2006) Jogo de computador2D

14

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

Rafael Campillo Lorenzo. “Cavaleiro dos Céus”

TCM-SPC (2005-2006) Jogo de computador2D

15

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.

Rafael Campillo Lorenzo. “Cavaleiro dos Céus”

TCM-SPC (2005-2006) Jogo de computador2D

16

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.

Rafael Campillo Lorenzo. “Cavaleiro dos Céus”

TCM-SPC (2005-2006) Jogo de computador2D

17

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

Rafael Campillo Lorenzo. “Cavaleiro dos Céus”

TCM-SPC (2005-2006) Jogo de computador2D

18

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.

Rafael Campillo Lorenzo. “Cavaleiro dos Céus”

TCM-SPC (2005-2006) Jogo de computador2D

19

� 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();

Rafael Campillo Lorenzo. “Cavaleiro dos Céus”

TCM-SPC (2005-2006) Jogo de computador2D

20

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);

}

Rafael Campillo Lorenzo. “Cavaleiro dos Céus”

TCM-SPC (2005-2006) Jogo de computador2D

21

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 doble-

buffering, y tiene dos ventajas fundamentales sobre el proceso normal de pintar o dibujar

directamente sobre la pantalla. [Brackeen2004]

Rafael Campillo Lorenzo. “Cavaleiro dos Céus”

TCM-SPC (2005-2006) Jogo de computador2D

22

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.

Rafael Campillo Lorenzo. “Cavaleiro dos Céus”

TCM-SPC (2005-2006) Jogo de computador2D

23

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.

Rafael Campillo Lorenzo. “Cavaleiro dos Céus”

TCM-SPC (2005-2006) Jogo de computador2D

24

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){}

}

Rafael Campillo Lorenzo. “Cavaleiro dos Céus”

TCM-SPC (2005-2006) Jogo de computador2D

25

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.

Rafael Campillo Lorenzo. “Cavaleiro dos Céus”

TCM-SPC (2005-2006) Jogo de computador2D

26

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

Rafael Campillo Lorenzo. “Cavaleiro dos Céus”

TCM-SPC (2005-2006) Jogo de computador2D

27

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.

Rafael Campillo Lorenzo. “Cavaleiro dos Céus”

TCM-SPC (2005-2006) Jogo de computador2D

28

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

Rafael Campillo Lorenzo. “Cavaleiro dos Céus”

TCM-SPC (2005-2006) Jogo de computador2D

29

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);

Rafael Campillo Lorenzo. “Cavaleiro dos Céus”

TCM-SPC (2005-2006) Jogo de computador2D

30

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;

};

Rafael Campillo Lorenzo. “Cavaleiro dos Céus”

TCM-SPC (2005-2006) Jogo de computador2D

31

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){

...

Rafael Campillo Lorenzo. “Cavaleiro dos Céus”

TCM-SPC (2005-2006) Jogo de computador2D

32

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.

Rafael Campillo Lorenzo. “Cavaleiro dos Céus”

TCM-SPC (2005-2006) Jogo de computador2D

33

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]

Rafael Campillo Lorenzo. “Cavaleiro dos Céus”

TCM-SPC (2005-2006) Jogo de computador2D

34

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

Rafael Campillo Lorenzo. “Cavaleiro dos Céus”

TCM-SPC (2005-2006) Jogo de computador2D

35

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

Rafael Campillo Lorenzo. “Cavaleiro dos Céus”

TCM-SPC (2005-2006) Jogo de computador2D

36

>9�����"��: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.

Rafael Campillo Lorenzo. “Cavaleiro dos Céus”

TCM-SPC (2005-2006) Jogo de computador2D

37

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.

Rafael Campillo Lorenzo. “Cavaleiro dos Céus”

TCM-SPC (2005-2006) Jogo de computador2D

38

>9�9��������� ������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.

Rafael Campillo Lorenzo. “Cavaleiro dos Céus”

TCM-SPC (2005-2006) Jogo de computador2D

39

>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

Rafael Campillo Lorenzo. “Cavaleiro dos Céus”

TCM-SPC (2005-2006) Jogo de computador2D

40

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.

Rafael Campillo Lorenzo. “Cavaleiro dos Céus”

TCM-SPC (2005-2006) Jogo de computador2D

41

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.

Rafael Campillo Lorenzo. “Cavaleiro dos Céus”

TCM-SPC (2005-2006) Jogo de computador2D

42

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.

Rafael Campillo Lorenzo. “Cavaleiro dos Céus”

TCM-SPC (2005-2006) Jogo de computador2D

43

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 del objeto sobre la pantalla.

vx, vy: velocidad de desplazamiento en cada coordenada

Rafael Campillo Lorenzo. “Cavaleiro dos Céus”

TCM-SPC (2005-2006) Jogo de computador2D

44

ox, oy, cx, cy: 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.

Rafael Campillo Lorenzo. “Cavaleiro dos Céus”

TCM-SPC (2005-2006) Jogo de computador2D

45

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.

Rafael Campillo Lorenzo. “Cavaleiro dos Céus”

TCM-SPC (2005-2006) Jogo de computador2D

46

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, que indexará el siguiente fondo a aparecer en pantalla, y dos variables de tipo

fondos, que serán las que estén siempre visibles.

Rafael Campillo Lorenzo. “Cavaleiro dos Céus”

TCM-SPC (2005-2006) Jogo de computador2D

47

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.

Rafael Campillo Lorenzo. “Cavaleiro dos Céus”

TCM-SPC (2005-2006) Jogo de computador2D

48

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).

Rafael Campillo Lorenzo. “Cavaleiro dos Céus”

TCM-SPC (2005-2006) Jogo de computador2D

49

@9���"����7&���:7�

@9,9���������!����������������������������������������������=�����

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.

Rafael Campillo Lorenzo. “Cavaleiro dos Céus”

TCM-SPC (2005-2006) Jogo de computador2D

50

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.

Rafael Campillo Lorenzo. “Cavaleiro dos Céus”

TCM-SPC (2005-2006) Jogo de computador2D

51

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).

Rafael Campillo Lorenzo. “Cavaleiro dos Céus”

TCM-SPC (2005-2006) Jogo de computador2D

52

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]

Rafael Campillo Lorenzo. “Cavaleiro dos Céus”

TCM-SPC (2005-2006) Jogo de computador2D

53

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:

Rafael Campillo Lorenzo. “Cavaleiro dos Céus”

TCM-SPC (2005-2006) Jogo de computador2D

54

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.

Rafael Campillo Lorenzo. “Cavaleiro dos Céus”

TCM-SPC (2005-2006) Jogo de computador2D

55

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

Rafael Campillo Lorenzo. “Cavaleiro dos Céus”

TCM-SPC (2005-2006) Jogo de computador2D

56

“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]

Rafael Campillo Lorenzo. “Cavaleiro dos Céus”

TCM-SPC (2005-2006) Jogo de computador2D

57

@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);

}

Rafael Campillo Lorenzo. “Cavaleiro dos Céus”

TCM-SPC (2005-2006) Jogo de computador2D

58

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:

.

Rafael Campillo Lorenzo. “Cavaleiro dos Céus”

TCM-SPC (2005-2006) Jogo de computador2D

59

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.

Rafael Campillo Lorenzo. “Cavaleiro dos Céus”

TCM-SPC (2005-2006) Jogo de computador2D

60

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.

Rafael Campillo Lorenzo. “Cavaleiro dos Céus”

TCM-SPC (2005-2006) Jogo de computador2D

61

getGrafico(String nombre), 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;

}

Rafael Campillo Lorenzo. “Cavaleiro dos Céus”

TCM-SPC (2005-2006) Jogo de computador2D

62

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();

...

Rafael Campillo Lorenzo. “Cavaleiro dos Céus”

TCM-SPC (2005-2006) Jogo de computador2D

63

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

Rafael Campillo Lorenzo. “Cavaleiro dos Céus”

TCM-SPC (2005-2006) Jogo de computador2D

64

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:

Rafael Campillo Lorenzo. “Cavaleiro dos Céus”

TCM-SPC (2005-2006) Jogo de computador2D

65

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

Rafael Campillo Lorenzo. “Cavaleiro dos Céus”

TCM-SPC (2005-2006) Jogo de computador2D

66

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

Rafael Campillo Lorenzo. “Cavaleiro dos Céus”

TCM-SPC (2005-2006) Jogo de computador2D

67

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.

Rafael Campillo Lorenzo. “Cavaleiro dos Céus”

TCM-SPC (2005-2006) Jogo de computador2D

68

-9��������������"�&��6D;�������� �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

Rafael Campillo Lorenzo. “Cavaleiro dos Céus”

TCM-SPC (2005-2006) Jogo de computador2D

69

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

Rafael Campillo Lorenzo. “Cavaleiro dos Céus”

TCM-SPC (2005-2006) Jogo de computador2D

70

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

Rafael Campillo Lorenzo. “Cavaleiro dos Céus”

TCM-SPC (2005-2006) Jogo de computador2D

71

-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

Rafael Campillo Lorenzo. “Cavaleiro dos Céus”

TCM-SPC (2005-2006) Jogo de computador2D

72

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.

Rafael Campillo Lorenzo. “Cavaleiro dos Céus”

TCM-SPC (2005-2006) Jogo de computador2D

73

59��� �&����

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.

Rafael Campillo Lorenzo. “Cavaleiro dos Céus”

TCM-SPC (2005-2006) Jogo de computador2D

74

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.

Rafael Campillo Lorenzo. “Cavaleiro dos Céus”

TCM-SPC (2005-2006) Jogo de computador2D

75

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.

Rafael Campillo Lorenzo. “Cavaleiro dos Céus”

TCM-SPC (2005-2006) Jogo de computador2D

76

E9���7�� ���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.

Rafael Campillo Lorenzo. “Cavaleiro dos Céus”

TCM-SPC (2005-2006) Jogo de computador2D

77

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.

Rafael Campillo Lorenzo. “Cavaleiro dos Céus”

TCM-SPC (2005-2006) Jogo de computador2D

78

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.

Rafael Campillo Lorenzo. “Cavaleiro dos Céus”

TCM-SPC (2005-2006) Jogo de computador2D

79

.9�B�B���6�;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

Rafael Campillo Lorenzo. “Cavaleiro dos Céus”

TCM-SPC (2005-2006) Jogo de computador2D

80

[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

Rafael Campillo Lorenzo. “Cavaleiro dos Céus”

TCM-SPC (2005-2006) Jogo de computador2D

81

/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

Colisiones, 4, 27, 40, 44, 51, 63, 64

Enemigo, 15, 44, 46, 47, 56, 74, 85

Evasión, 32, 33, 34

Eventos, 9, 11, 25, 26, 41, 49, 57, 73, 76,

77

Fotogramas, 24, 44, 51, 73

Gráfica, 9, 11, 16, 22, 68, 73, 77

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,

41, 42, 44, 45, 46, 47, 51, 55, 57, 63,

64, 70, 73, 74, 75, 76, 77, 83, 84, 85

Persecución, 32, 33, 34

Photoshop, 69, 70, 71, 72, 73

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

Rafael Campillo Lorenzo. “Cavaleiro dos Céus”

TCM-SPC (2005-2006) Jogo de computador2D

82

,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

Rafael Campillo Lorenzo. “Cavaleiro dos Céus”

TCM-SPC (2005-2006) Jogo de computador2D

83

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.

Rafael Campillo Lorenzo. “Cavaleiro dos Céus”

TCM-SPC (2005-2006) Jogo de computador2D

84

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”.

Rafael Campillo Lorenzo. “Cavaleiro dos Céus”

TCM-SPC (2005-2006) Jogo de computador2D

85

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.

Rafael Campillo Lorenzo. “Cavaleiro dos Céus”

TCM-SPC (2005-2006) Jogo de computador2D

86

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.

Rafael Campillo Lorenzo. “Cavaleiro dos Céus”

TCM-SPC (2005-2006) Jogo de computador2D

87

,49�9����1����0���!������#���1����������=����9�

Rafael Campillo Lorenzo. “Cavaleiro dos Céus”

TCM-SPC (2005-2006) Jogo de computador2D

88

Rafael Campillo Lorenzo. “Cavaleiro dos Céus”

TCM-SPC (2005-2006) Jogo de computador2D

89