RECREACIÓN DEL JUEGO MANIC MINER PARA MOVILES

 
SEGUIR LEYENDO
RECREACIÓN DEL JUEGO MANIC MINER PARA MOVILES
ESCUELA TÉCNICA SUPERIOR DE INGENIERÍA INFORMÁTICA

                    TITULACIÓN: INGENIERÍA INFORMÁTICA

   RECREACIÓN DEL JUEGO MANIC MINER
                              PARA MOVILES

AUTOR: JOSÉ MANUEL GARCÍA MAESTRE

DIRIGIDO POR: JOSÉ RAMÓN PORTILLO FERNÁNDEZ

DEPARTAMENTO: MATEMÁTICA APLICADA I

Sevilla, Septiembre de 2010
RECREACIÓN DEL JUEGO MANIC MINER PARA MOVILES
ÍNDICE

1.   Introducción      ……………………………………………….                4
     1.1 Introducción a los videojuegos …………………….         4
     1.2 Introducción a las recreaciones ……………………         6
     1.3 Introducción a los videojuegos para móviles ..   8

2.   Definición de objetivos …………………………………………             10

3.   Análisis de antecedentes y aportaciones realizadas   12

     3.1. Análisis de antecedentes ……………………………... 12

       3.1.1. Manic Miner de 1983 …………………………….            12

       3.1.2. Conceptos para la creación de videojuegos   14

     3.2 Aportaciones realizadas ………………………………             18

4.   Análisis de requisitos    ……………………………………… 20

5.   Diseño        ………………………………………………………                  24

6.   Implementación ………………………………………………..                  31

     6.1. Introducción ……………………………………………….                31

     6.2. Tamaño de los gráficos y programas usados       32

                                                               2
RECREACIÓN DEL JUEGO MANIC MINER PARA MOVILES
para las imágenes

      6.3. Clase MidletInicio …………………………………….         38

      6.4. El game loop del juego …………………………….        40

      6.5. Implementación del salto ………………………..       48

      6.6. Implementación de las colisiones ………………    50

      6.7. Implementación de la barra de aire ………..   67

7. Manual de usuario    .......…………………………………..        71

8. Pruebas ……………………………………………………………...                 72

9. Conclusiones    …………………………………………………….              73

10. Bibliografía   …………………………………………………….              74

                                                           3
RECREACIÓN DEL JUEGO MANIC MINER PARA MOVILES
1. INTRODUCCIÓN
1.1 Introducción a los videojuegos

Desde el principio de los tiempos el hombre ha necesitado algo para
divertirse, este hecho se da también en los animales. Los videojuegos ya
no son un fenómeno aislado, es difícil ir a un sitio y no encontrarse a
alguien jugando con una consola portátil, ya sea un móvil.

A lo largo del tiempo se ha creado muchas clases de juegos muchas de
ellos se han pasado a los videojuegos como los juegos de deportes, juegos
de estrategia como el ajedrez o las damas, el parchís o las cartas.

Los videojuegos es una forma de diversión que mueve mucho dinero, así,
en España, los ingresos derivados del uso de los videojuegos mueve más
dinero que el cine y la música juntos. Es un mercado inmenso que está
creciendo cada año a pasos agigantados. Grandes compañías ganan
grandes sumas de dinero en este mercado como SNK, Sega, Nintendo, etc.
y otras crecen rápidamente como Sony desde el lanzamiento de
PlayStation, avanzando actualmente con la psp.

En 2009, este sector generó 55.000 millones de dólares (41.200 millones
de euros) solo en venta de software. En hardware recaudaron 22.000
millones. Si se juntan los dos apartados, los 77.000 millones obtenidos se
acercan cada vez más a la caja de Hollywood, que en 2009 estuvo en los
85.000 millones de dólares en todo el mundo.
http://www.navegandoxlared.es/?p=748

http://www.elpais.com/articulo/ocio/industria/videojuego/crece/Espana/venta/consolas/elpe
puteccib/20080410elpciboci_1/Tes

                                                                                        4
RECREACIÓN DEL JUEGO MANIC MINER PARA MOVILES
1. Venta de videojuegos en España en millones

En la venta de videojuegos España es la cuarta a nivel Europeo detrás de
Reino Unido, Alemania y Francia.

El principal mercado de España en videojuegos es del extranjero y aunque
se vende mucho no existe grandes compañías que arriesguen en este
ámbito en España, por lo que existen riesgos pero también oportunidades
de que el país adquiera dinero en este ámbito, ya existen estudios
especializados para formar a personas para crear videojuegos en Madrid y
fomentar su desarrollo.

En lo que se refiere a sistema portátil todo comenzó con la GameBoy de
Nintendo, y desde entonces casi todo el mundo se ha adentrado en el
espacio portátil.

La diferencia de estos, es que los juegos portátiles están al alcance de
todos, el hardware es accesible y muy asequible. También se han unido a
este mercado los móviles que solo se usaban para llamar y ahora poseen

                                                                           5
RECREACIÓN DEL JUEGO MANIC MINER PARA MOVILES
un repertorio completo de juegos y muchas compañías apuestan por este
mercado.

Los juegos para móviles son llevados continuamente en nuestra vida
diaria, para la comunicación del trabajo, esto ofrece ventajas sobre los
videoconsolas portátiles que solo son usados para jugar y no siempre se
lleva en el bolsillo. Cualquier persona que lleve un móvil y sienta
necesidad de divertirse puede utilizar su teléfono aunque el sistema de
juego sea peor que el videojuego portátil.

1.1 Introducción a las recreaciones

En lo que se refiere a las recreaciones de juegos ya inventados, muchas
empresas importantes han realizado esto debido a que sería un éxito
garantizado si el juego es popular, además los costes y los riegos de un
desarrollo se reducen en gran medida cuando se adapta un juego ya
terminado.

Un problema al adaptar un juego de un sistema a otro son los gráficos:
convertir gráficos creados con píxeles de una pantalla a otra puede ser un
gran problema porque los gráficos normalmente se han creado teniendo
muy en cuenta las especificaciones de la plataforma de destino. El
diseñador está muy al tanto de las limitaciones del sistema y de cómo
estas afectan a sus imágenes. Todas las particularidades del sistema
tienen su efecto en el diseño con pixeles. Algunos sistemas han limitado
las paletas, y han reducido el número de colores disponibles. Otros no
pueden mover grandes imágenes, así que los objetos individuales tienen
que ser pequeños. Los sistemas cuya resolución es menor exigen un gran
esfuerzo para hacer que los objetos que aparecen en pantalla sean más
pequeños sin utilizar tantos detalles que se vuelvan irreconocibles. Los
antiguos sistemas que utilizaban cartuchos limitaban el potencial por su
escasa capacidad de almacenamiento.

                                                                             6
RECREACIÓN DEL JUEGO MANIC MINER PARA MOVILES
Los teléfonos tienen una gran variedad de resoluciones y paletas, y el
desarrollador tiene que decidir entre crear gráficos para el mínimo común
denominador o recrear la imagen para cada uno de los tamaños de
pantalla diferentes. La primera opción es la peor, ya que los propietarios
de los teléfonos móviles nuevos y potentes pueden encontrarse con que
los juegos se reproducen en ventanas minúsculas dentro de sus enormes
pantallas.

Grandes compañías han decidido adaptar sus juegos para otros sistemas
así tenemos el salto de Yoshi’s Island SNES a Yoshi’s Island GBA, Metal
Slug arcade a Metal Slug para teléfono móvil.

Ilustración 1 Metal Slug Móvil       Ilustración 2 Metal Slug Arcade

Otros juegos han sido también recreados por fans de usuarios
programadores para PC con mejores gráficos pero con una jugabilidad
igual de buena que en la versión original, como puede ser Maniac Mansion
de LucasArts para PC llamado Maniac Mansion Deluxe.

                                                                          7
RECREACIÓN DEL JUEGO MANIC MINER PARA MOVILES
2 Goody para Spectrum                        3 Remake de Goody Para PC

        3 Maniac Mansion (PC)     5 Maniac Mansion Deluxe (PC)

1.3 Introducción a los videojuegos para móviles

El botón de acción, que en casi todos los mandos de las consolas se
controla con la otra mano, en los móviles está en el centro del panel de
control. Como es difícil pulsar ese botón al mismo tiempo que se está
pulsando una dirección muchos juegos lo que hacen es utilizar el teclado
numérico como mando alternativo. No es un sistema ideal pero si lo
suficientemente bueno para que la gente se descargue y disfrute de
cientos de juegos.

El teléfono móvil es una plataforma única para los desarrolladores. Los
juegos no se lanzan para una o dos plataformas, como en el caso de las
consolas, ni se desarrollan con unas especificaciones de hardware
mínimas o máximas, como en los PC. Cada móvil tiene una resolución de
                                                                           8
RECREACIÓN DEL JUEGO MANIC MINER PARA MOVILES
pantalla diferente y un hardware diferente con un sistema operativo
diferente por lo que los juegos que se desarrollen tienen que verse y
poder jugarse bien en cientos de teléfonos. Con cientos de sistemas, los
gráficos deben optimizarse por familias de teléfonos que tengan una
resolución de pantalla similar.

Esto es solo los móviles de Nokia:

Los juegos deben ser lo suficientemente cortos como para que los
consumidores jueguen durante breves periodos de tiempo libre, por
ejemplo, entre dos clases o reuniones, o mientras esperan en una cola.
Puede haber nuevas formas de hacerlo y, si se llevaran a cabo, podrían
expandir el mercado de los juegos exponencialmente. Gracias al bluetooth
o la tecnología de internet para móviles podría haber juegos que se
jugasen multijugador.

                                                                           9
RECREACIÓN DEL JUEGO MANIC MINER PARA MOVILES
2. DEFINICIÓN DE OBJETIVOS

      El objetivo principal del proyecto consiste en la elaboración de una
recreación del juego Manic Miner de Spectrum para móviles, con la misma
jugabilidad pudiéndose mejorar los gráficos.

      A continuación desarrollamos una serie de subobjetivos:

      - Un objetivo importante es que funcione en la mayoría de los
        teléfonos móviles de diferentes generaciones, ya que a
        diferencia de otros aparatos eléctricos, existe una gran cantidad
        diferentes de móviles más antiguos que aun se venden por ser
        más económicos y más caros con mayor prestaciones y pantallas
        más grandes que los antiguos.

      - El teclado debe ser fácil de manejar.

      - Los gráficos se pueden mejorar, para que sea más atractivo al
        mercado de los juegos actuales para móviles

      - Conseguir que el muñeco se choque.

      - Conseguir que los colores no molesten a la vista.

      - Conseguir que el usuario diferencie entre el fondo y los objetos
        con los que el personaje puede colisionar.

                                                                           10
- Tanto la jugabilidad como la dificultad debe ser idéntica al del
        juego original ya que es una recreación.

       El Spectrum fue uno de los ordenadores más vendidos en el
mercado doméstico, en la época de los 80, haciendo la delicia de miles de
aficionados a los juegos y la informática. Aun hoy en día existen fans que
coleccionan y juegan a juegos con la ayuda de emuladores. Hubo juegos
muy buenos y populares como el Manic Miner, Goody, Lode Runner,
Snake, etc. Así que es un proyecto interesante, apoyarme en juegos que se
hicieron que tuvieron éxito para aprender y conseguir un juego con éxito
en el mercado actual de la telefonía móvil, por la popularidad, la
jugabilidad y el entretenimiento de aquellos juegos de 2 dimensiones,
además se siguen usando estas 2 dimensiones en los juegos de móvil más
que en ninguna otro sistema.

                                                                           11
3. ANÁLISIS DE ANTECEDENTES
      Y APORTACIÓN REALIZADA

3.1 ANALISIS DE ANTECEDENTES

3.1.1 Manic Miner de 1983

     El juego original Manic Miner se realizo para ZX Spectrum por
Matthew Smith, lanzado por Bug Byte en 1983 y relanzado más tarde por
Software Projects. El juego se inspiro en el juego Miner2049er para Atari
800.

       Manic Miner nos pone en el papel de un minero en el que tenemos
que recorrer diferentes salas e ir cogiendo llaves para salir de cada una de
ellas. También nos encontrábamos con animales, monstruos e incluso
objetos que se mueven y que teníamos que esquivar. Esto nos lo hace
más difícil, y más divertido, provocando la muerte instantánea si nos
chocamos con ellos o si caíamos de una altura muy grande.

Además las salas tenían un oxigeno que se iba agotando poco a poco
provocándonos la muerte si llegábamos a 0.

                                                                          12
3. Niveles de Manic Miner (ZX Spectrum)
Manic Miner contaba con 20 niveles cada uno de ellos con diferentes
niveles de dificultad y solo 3 vidas, por lo que es difícil pasarse el juego,
aunque así es muy entretenido.

                                              Manic Miner hacía un
                                              alarde de coloridos,
                                              diseño de niveles,
                                              efectos de sonido y
                                              música que lo elevó a
                                              los más alto en el
                                              mundo de los
                                              videojuegos,
4. Pantalla de Manic Miner                    posteriormente dio
paso a una secuela que aumentaba considerablemente el número de

                                                                                13
niveles, llamada “Jet Set Willy”.

También destacar que Manic Miner fue el primer juego de ZX Spectrum
que acompañaba una melodía al jugar, conocida como “En el Salón del
Rey de la Montaña”. Fue emplazado en el puesto 25 de “Your Sinclair
oficial top 100” de los juegos de Spectrum y fue el ganador de un “Golden
Joystick Award” por el mejor juego arcade por la revista “Computer &
video games” en la edición de 1983 y nombrado el tercer juego mejor del
año por la misma revista.

3.1.2. Conceptos para la creación de videojuegos

       En un videojuego además del código de la lógica, tenemos que
hacer que las animaciones se muevan al pulsar una tecla o que un gráfico
se mueva hacia un lado o hacia otro. Hay que distinguir entre imagen y
sprite primero.

      Ya en la década de los 80 se usaban sprites para desarrollar los
videojuegos. Un sprite es un conjunto de imágenes que representan un
personaje, u objeto el cual puede tener una animación interna o no
tenerla. Generalmente son utilizados para producir una animación interna,
como un personaje corriendo, alguna expresión facial o un movimiento
corporal.

5. Sprite del personaje principal del juego desarrollado

El paso de una imagen a otra del sprite da lugar a la animación interna,
haciendo parecer que el personaje anda, solo faltaría añadirle que el

                                                                           14
sprite se desplace por la pantalla. Para que el sprite del personaje se
mueva por la pantalla no hace falta que este animado, pero si no lo
animamos se desplazaría por la pantalla sin mover las piernas.

Eso es lo que he usado para crear los personajes y es lo que usa muchos
juegos de 2 dimensiones, para crear el mapa he usado una técnica que
consiste en dividir el mapa en cuadrados:

Dentro de cada cuadrado pondremos una serie de elementos llamado tiles
(baldosas en español).

6. Tiles del primer nivel del juego Manic Miner desarrollado

A cada tile le corresponde un numero, por ejemplo, en el mapa de tiles de
arriba imagen con numero 6, el árbol verde seria el tile número 2, el

                                                                          15
ladrillo, el numero 3…. El 0 se reservaría para decir que no hay nada. Y se
irían colocando en una matriz para generar el mapa. Por ejemplo,
suponiendo una matriz de 5x5 y rellenándola:

                        int tilesMapa [] ={{2,0,0,0,3}

                                           {3,1,0,0,3}

                                           {3,0,0,0,3}

                                           {3,0,0,0,3}

                                          {1,1,1,1,1}};

Creando o utilizando un método que coloque las imágenes de los tiles
correctamente según la matriz y dibujándolo quedaría:

A la hora de desarrollar el código del juego, he de decir que el juego se
ejecuta en un bucle infinito, igual que todos los juegos, llamado “game
loop”. En cada vuelta del bucle, se comprueba si el usuario ha pulsado una
tecla, las acciones a tomar de la tecla pulsada, las animaciones internas,
comprobar las colisiones y su acción dependiendo de con que choque, y al
final de cada bucle se pinta en la pantalla:

                                                                              16
7. Estructura de un game loop

                                17
3.2 APORTACIONES REALIZADAS

      El juego que he desarrollado ya no funciona en un único sistema
como los juegos de Spectrum sino que funciona en una gran cantidad de
móviles, he aprovechado el hecho de tener que coger las imágenes del
juego original y añadirle mas colores.

       También he introducido un fondo a los niveles, de manera que
visualmente se pueda observar en qué lugar se encuentra el personaje. El
juego original lo mostraba con un texto que ponía debajo, he decidido
quitar dicho texto dado e introducir un fondo, de manera que el usuario
pueda imaginárselo. Decidí no añadir las letras del lugar donde estaba
dado que en algunos móviles quizás no podrían mostrarse todo el texto
por la longitud del nombre del lugar, ya que dependiendo del móvil las
letras son mas grandes o mas chicas y pueden caber en la pantalla o no
caber.

      Dado que cada móvil posee una resolución distinta, hay 2 formas de
desarrollar los gráficos para móvil:

-La primera consiste en hacer los gráficos para que funcione en el móvil
con la pantalla de menor, de manera que si tenemos un móvil con mayor
resolución se muestre más elementos, pero se siga viendo todo lo
importante.

-La segunda consiste en desarrollar gráficos diferentes para diferentes
resoluciones de móviles.

                                                                          18
Evidentemente la segunda opción es mejor, ya que el usuario verá las
imágenes acorde a su pantalla, pero opte por la primera opción ya que no
tengo un equipo de diseñadores gráficos que me hagan dicho trabajo que
requiere mucho tiempo, dado que los dibujos es a nivel de pixeles y no se
pueden aumentar automáticamente y que quede bien en móviles de
mayor tecnología. Además con la primera opción solo necesito desarrollar
una versión para todos los móviles y no una para cada móvil, con sus
gráficos de diferente tamaño.

Esta misma opción uso Sega con su Master System de mayor resolución
que la Game Gear en el juego Sonic.

Sega adaptó el sonic The hedgehog 2 de Master System a Game Gear
usando los sprites del anterior.

8. Sonic The Hedgehog 2 (Master System)   Sonic The Hedgehog 2 (Game Gear)

Como se observa en la imagen, se ve mucho más el escenario en la imagen
de Master System que en la Game Gear por la resolución y al no cambiar
el tamaño de los sprites y tiles del escenario.

Del mismo modo si el juego desarrollado lo ponemos en un móvil con
mayor resolución se verá más el escenario que con uno de menor
resolución ya que no he hecho una versión del juego para cada resolución
de móvil o tipos de móvil.

                                                                             19
4. ANÁLISIS DE REQUISITOS

Requisito 1

       Uno de los requisitos para que el juego funcione en una gran
cantidad de móviles con diferentes sistemas operativos es necesario que
el lenguaje de programación sea J2ME, ya que está pensado para
funcionar tanto en móviles o PDAs con cualquier sistema operativo.

Requisito 2

       El juego debe tener la misma jugabilidad que el original, para ello
me fijo cuantos pixeles se mueve por fotograma el juego original, el
tamaño de todos los elementos del juego (tiles, sprites, anchura del juego,
etc.). De esta manera podemos conseguir un juego con los movimientos
idénticos al original y posición de sus elementos, y por tanto la misma
jugabilidad.

Requisito 3

       En lo que se refiere al objetivo de facilidad de manejo, es una de las
desventajas de los móviles frente a las consolas portátiles ya que los
paneles de control son muy malos: son rígidos y prácticamente inútiles
para juegos de acción. Es casi imposible mover el dedo pulgar por un disco
plano con precisión y velocidad y como todo jugador sabe, quien no
controla el juego, muere. Por eso se necesita que además de controlar el
personaje con el disco se pueda controlar con los números: 6 para la
derecha 4 para la izquierda y 5 para saltar, ya que están más separadas en
el teléfono.

                                                                           20
Requisito 4

      Las animaciones deben ser iguales parecidas, o mejores que la
original, ya que estamos desarrollando una recreación y el aspecto visual
debería ser parecido y que no parezca otro juego.

Requisito 5

      Para conseguir que los colores no molesten a la vista, hay que elegir
colores parecidos al juego original y colores oscuros.

Requisito 6

      Para conseguir que el usuario diferencie entre el fondo y los objetos
con los que el personaje puede colisionar hay que usar mas contraste de
color entre el fondo y los objetos de colisión

Requisito 7

       Hay varios tipos de objetos que dependiendo de la colisión con ellos
el personaje hará una cosa u otra. A continuación mostramos que hace
cada objeto, desarrollando este requisito funcional:

            Hay un tile al que llamaremos bloque que el personaje chocara
            con el siempre.

9. Bloque

                                                                         21
Existe otro tile al que llamaremos suelo y que el personaje no
                        choca a no ser que este apoyado encima de él, es decir a no
                           ser que choque con la cara de arriba, de ahí el nombre de
     10. Suelo                                                    suelo que le damos.

                           Existe otro suelo que he llamado “suelo que se cae” que al
                              pasar sobre él se va desbaratando a medida que pasa el
                          tiempo sobre él, hasta que el personaje se queda sin suelo,
11. Suelo que se cae                   provocando que el personaje caiga hacia abajo.

                       Existe otro tipo de objeto, un tile que he llamado “muerte”
                       que al colisionar contra el provoca la muerte del personaje.

   12. Muerte

                       Tile llamado llave que si el personaje colisiona con el
                       desaparecerá del escenario haciendo entender que se ha
                       cogido una llave más.
   13. Llave

                       Este objeto es un tile parecido al suelo, solo se puede
                       colisionar con la parte superior pero provocando que el
                       personaje se deslice, lo he llamado “cinta” de cinta
   14. Cinta           transportadora.

                                                                                      22
Existe un tipo de sprite que son los enemigos y que al chocar
               con el provocan la muerte del personaje

15. Monstruo

                 Esto es una puerta, que debería ser un sprite, ya que ocupa
                 más que un solo tile de 8x8 pixeles, esta puerta ocupa 16x16
                 pixeles. Al colisionar el personaje con él pasara de nivel si el
                 personaje tiene todas las llaves.

Requisito 9

         La puerta debe abrirse cuando el personaje coja todas las llaves del
nivel.

Requisito 10

      Coger las llaves y pasarse el nivel da una serie de puntos. Deben ser
iguales o parecidos al original: 100 puntos por cada llave. 18 puntos por
cada porcentaje de la barra de aire al final.

Requisito 11

       Al pasarse el nivel se ilumina el escenario con colores y se disminuye
la barra para conseguir los puntos por el aire sobrado.

                                                                               23
5. DISEÑO
Antes de empezar a desarrollar el diseño estuve investigando a ver qué
programa era el adecuado para realizar videojuegos para móviles con
J2ME, busque en foros de desarrollo y descubrí que netBeans a diferencia
de Eclipse tenía una interfaz para desarrollar los gráficos del juego, así que
me decante por él, ya que me ahorra mucho trabajo al verlo visualmente
en vez de crear la matriz del mapa yo. Aquí muestro algunas capturas de
interfaces del desarrollo del escenario y los enemigos en netBeans del
juego una vez completado:

              16. Pantalla de netBeans para editar el diseño de niveles y personajes

      El tipo de fichero dedicado al desarrollo gráfico, está situado en la
pestaña Projects y viene indicado con un símbolo de un mando de

                                                                                       24
videojuego. Este fichero es una clase que se genera automáticamente con
los elementos que introduzcamos en la interfaz gráfica de la derecha. Se
puede ver el código pulsando en la pestaña source una vez se ha abierto el
fichero aunque solo se puede modificar la parte no generada
automáticamente. O también se puede construir gráficamente con la
pestaña Game Builder, para que se genere automáticamente el código.

La interfaz gráfica principal de netBeans para desarrollar juegos para
móviles se muestra dividida en tres zonas:

-Scenes: Es la composición de un escenario entero, con los sprites y tiles
colocados en una zona. Cuando creamos una escena colocaremos los
TiledLayer y sprites en un escenario.

-TiledLayer: Es donde se compone los mapas de tiles, es decir, es donde se
hará la matriz donde se colocará los tiles, pero visualmente, es una de las
grandes ventajas de esta interfaz, ya que no tengo que hacerlo antes en
papel y puedo ver cómo queda o modificar algo visualmente sin tener que
contar que fila y columna es la que falla. Además se pueden añadir tiles
animados.

-Sprites: Es donde se colocan los sprites de los personajes y donde se edita
su animación.

A continuación muestro imágenes de los editores de cada una de estas
tres zonas:

                                                                             25
17. Editor de Sprites

18. Editor de TiledLayer

                           26
19. Editor de Scene
      En el editor se puede tanto colocar los Sprites y tiles como indicar
en qué capa se encuentra dicho tile o Sprite de manera que quede
dibujado más hacia el fondo o hacia afuera.

                                                                             27
28
En este diseño la clase que se ejecuta en primer lugar será MidletInicio,
esta creara un hilo con la ejecución del método run(), de MinerCanvas, el
cual iniciará los parámetros iniciales para configurar el escenario inicial y
ejecutara el game loop.

En el game loop tendremos que comprobar las teclas pulsadas, mover el
sprite del personaje dependiendo de la tecla pulsada, comprobar si existe
colisión al moverse el personaje, actuando en cada caso dependiendo del
objeto con el que colisione, sumaremos los puntos obtenidos si cogemos
una llave o pasamos el nivel, se comprobara si se ha muerto el personaje,
etc.

 En lo que se refiere al nivel en el game loop, el nivel será el encargado de
pintar todo, en cada ciclo del game loop, ya que es el que posee toda la
información necesaria.

El nivel tendrá información sobre la posición de los objetos al inicio del
nivel, los monstruos que existen en dicho nivel, las llaves, etc. Todo
dependiendo del nivel en que nos encontremos, para ello he creado una
clase llamada FabricaNivel que obtendrá todo lo necesario dependiendo
del nivel que nos encontremos usando el parámetro “nivel” de tipo
entero.

FabricaNivel se comunicará con otra fábrica que es generada por
NetBeans automáticamente al pintar los escenarios y colocar los sprites,
aunque a diferencia de la fábrica que hemos creado, esta no usa un

                                                                             29
número indicando el nivel para devolver los sprites y tiles sino que cada
método tiene un nombre distinto para cada Sprite y Personaje.

La clase Monstruo hará que el monstruo se mueva, independizando esta
tarea de MinerCanvas y de Nivel.

                                                                            30
6. IMPLEMENTACIÓN
   6.1.   Introducción

      “J2ME es un entorno de producción para pequeños dispositivos que
permite la ejecución de programas creados en Java. Una de las principales
capacidades que añade esta tecnología a nuestros terminales es la
posibilidad de descargar y ejecutar juegos con una calidad razonable. Hoy,
nuestros teléfonos móviles corren auténticos sistemas operativos. El más
conocido quizás es Symbian, que es el corazón de gran cantidad de
móviles, como los Nokia, Sony-Ericsson, Motorola y otros.

      MIDP (Mobile Information Device Profile), define los requerimientos
mínimos para poder ejecutar programas J2ME, sin embargo, ofrecían poca
ayuda a la hora de crear juegos, por lo que había que recurrir a librerías
propias de cada fabricante, haciendo necesario crear diferentes versiones
de un juego para cada fabricante. La versión 2.0 subsana de alguna
manera este problema, y nos ofrece una API mucho más adecuada para la
programación de juegos.”

“J2ME se basa en los conceptos de configuración y perfil. Una
configuración describe las características mínimas en cuanto a la
configuración hardware y software. La configuración que usa J2ME es la
CLDC (Connected Limited Device Configuration).”

“CLDC es una especificación general para un amplio abanico de
dispositivos, que van desde PDAs a teléfonos móviles y otros. Un perfil
define las características del dispositivo de forma más específica.
MIDP(Mobile Information Device Profile) define las APIs y características
hardware y software necesarias para el caso concreto de los teléfonos
móviles.”

(Texto del libro: Programación de juegos para móviles con J2ME.

Autor: Alberto García Serrano.

                                                                            31
www.agserrano.com)

Así que decidí usa la versión 2.0 de MIDP (MIDP2), por el tema que tiene
una API que define algunas clases para videojuegos ahorrándonos ese
trabajo.

      Antes de implementar y mientras estaba realizando el diseño tuve
que decidir que tamaño quería para el juego, explique más arriba en el
apartado aportaciones realizadas que hice los sprites lo más pequeño
posible de manera que pueda funcionar bien desde móviles con pequeña
resolución hasta los que tienen gran resolución, además decidí elegirlo así
porque cuando uno ve la pantalla de un móvil esta mucho más cerca de la
pantalla que cuando coge un videojuego que no sea portátil.

   6.2.   Tamaño de los gráficos y programas usados para las imágenes

      Lo próximo era sacar las imágenes del juego original para ello me
descargue un emulador de Spectrum llamado fuse y una imagen que
mostraba todos los escenarios del juego original:

                                                                           32
20. Mapas de Manic Miner

       Necesite un programa llamado “camStudio” para grabar en un video
lo que muestra la pantalla del ordenador y así obtener las animaciones de
los personajes. Una vez tenía el video en formato .avi use un programa
que llamado “video to jpg converter” que convertía un video .avi en
imágenes por cada fotograma grabado, pudiendo así obtener la imagen de
cada una de las animaciones del mapa y de los personajes editando en
photoshop.

El tamaño de los tiles era de 8x8 pixeles, que era el mismo tamaño que en
el programa fuse, ya que no estiraba la imagen, así que use ese mismo
tamaño para mis tiles, los averigüé usando el photoshop y usando unas
guías sobre el escenario para ver los diferentes elementos:

                                                                       33
21. Método usado para averiguar cual eran los tiles
Dado que todos los elementos de un mapa con tiles tienen que ser iguales,
averiguando el tamaño de uno obtenía el tamaño de los demás y por
tanto la de la imagen, así que elegí el tamaño del ladrillo amarillo para
averiguarlo.

La clase TiledLayer de MIDP2 nos permite almacenar todos los tiles en un
solo archivo gráfico en lugar de almacenarlo por separado, esto nos ofrece
una gran ventaja en cuanto a memoria, organización de contenidos y el
tiempo de ejecución se reduce al tener que usar solo un archivo para
varios tiles en vez de un archivo para cada tile.

      Decidí dividir cada fichero de tiles por niveles, de manera que la
organización y la ejecución sea mejor, así tenemos los tiles del mapa1 en
un único archivo:

                                                                            34
22. Tiles mapa1

La forma en que estén dispuestos en el archivo gráfico no es importante.
Siempre se capturan de izquierda a derecha y de arriba hacia abajo.

        Ejemplo:

Image imagen = Image.createImage(“/tiles.png”);

TiledLayer tiledlayer = new TiledLayer(10,10, imagen, 8,8);

Creamos un mapa de tiles de 10x10 y cada tile ocupa 8 pixeles de ancho y
8 pixeles de alto respectivamente.

En la imagen superior se observa muchas llaves, cada una de esas llaves es
un frame (un fotograma) de una animación.

      Igual ocurre con la clase Sprite de MIDP2 que nos ofrece la
posibilidad de poner todas los frames de un personaje en un único
archivo. Se captura de izquierda a derecha y de arriba hacia debajo de la
misma forma.

Ejemplo:

                                                                            35
Try{

       Imagen = Image.createImage(“/hero.png”);

}catch (IOException ioe) {};

Sprite sp = new Sprite(imagen,10,16);

Cada frame del sprite ocupa 10 pixeles de ancho y 16pixeles de alto
respectivamente.

Todo el código de creación de Sprites, TiledLayer y Scenes lo genera
automáticamente en una clase, NetBeans al indicárselo en la interfaz
gráfica, creando los métodos necesarios para obtenerlos.

A continuación muestro una serie de medidas que tome para crear el
juego (anchoxalto) :

Tiles de 8x8 pixeles

Tamaño del mapa: 32x16 tiles -> 256x128 pixeles

PIXELES PERSONAJES: (ANCHO X ALTO)

MANIC MINER: 10X16 pixels

MONSTRUO 1: 12X16 pixels

MOVIMIENTOS

                                                                       36
A LO ANCHO: 9.41 segundos en 28 tiles. -> avanza de pixel en pixel

Pasar a pixeles por segundo -> 28tiles en 9.41 segundos -> 2.97 tiles/s ->
23.8 pixeles/s

SALTO ARRIBA: 1.6 segundos. 2 tiles y medio que alcanza de altura existen
aceleración y deceleración.

SALTO HACIA DELANTE: 1.6 segundos ->2 tiles y medio de altura, 4 tiles a
lo ancho, aceleración hacia arriba igual, misma velocidad a lo ancho que si
funcionase normal. (Avanza de tile en tile hacia delante y hacia arriba
acelera y desacelera)

Caída libre: 2.30 segundos 8 tiles
A PARTIR DE 5 TILES DE CAIDA SE MUERE EL PERSONAJE

Tiempo de aire del personaje -> 2 minutos y 35 segundos.

23. Imagen que muestra a partir de que altura muere el personaje

                                                                             37
El tiempo en cada dibujado lo calculé haciendo que el muñeco fuese de un
lado a otro de la pantalla y midiendo el nº de segundos que tardaba en
recorrer 30 tiles -> pase los tiles a pixeles multiplicando por 8 ya que
recorría en anchura los pixeles y vi cuanto tiempo tardaba en recorrer un
pixel, ya que es lo que recorre el personaje en un ciclo. Y obtuve 62
milisegundos.

6.3 Clase MidletInicio

Añado una serie de códigos importantes explicándolos:

package ManicMiner;

import javax.microedition.midlet.*;

import javax.microedition.lcdui.*;

/**

* @author supervisor

*/

public class MidletInicio extends MIDlet implements CommandListener {

  Command exit;

  Display d;

  MinerCanvas mc;

  public MidletInicio(){

      exit = new Command("Salir",Command.EXIT, 2);

                                                                        38
d = Display.getDisplay(this);

    mc = new MinerCanvas();

    mc.addCommand(exit);

    mc.setCommandListener(this);

    new Thread(mc).start();

}

public void commandAction(Command c, Displayable d){

    if(c==exit)

    {

        destroyApp(false);

        notifyDestroyed();

    }

}

public void startApp() {

    d.setCurrent(mc);

}

public void pauseApp() {

}

public void destroyApp(boolean unconditional) {

}

                                                       39
}

Esta es la primera clase que se ejecuta (MidletInicio), empieza
ejecutándose en el constructor, en la cual se crea un comando para salir
de la aplicación, con exit = new Command("Salir",Command.EXIT, 2); .

Y se añade a mc de la clase GameCanvas con mc.addCommand, y la clase
que lo escuchara que no será mc sino MidletInicio.

Se crea un objeto “mc” de clase MinerCanvas que hereda de GameCanvas:
    mc = new MinerCanvas();

Se crea un nuevo hilo de ejecución y en el cual se ejecutara el método run
de mc con:
new Thread(mc).start();

6.4 El game loop del juego

El método run es el que poseerá el game loop, con todas las
comprobaciones lógicas (colisiones, si ha muerto el personaje, si te pasas
el nivel) del juego y dibujarlo en cada ciclo del bucle.

Muestro el game loop para después explicar los distintos parámetros que
he puesto.

                                                                           40
public void run(){

    int puntosAux;

    long start, end;

    int duration;

   // int sleepTime = 42; // Para jugar más rápido

    int sleepTime = 62;

/*Lo uso para encontrar errores,

ya que se ejecuta muy lentamente el juego

1 ciclo cada 1000 milisegundos -> 1ciclo/segundo*/

// int sleepTime = 1000;

    //Dice si se ha pasado el juego

    boolean gameCompleted = false;

    Graphics g = this.getGraphics();

// Game loop 1

    while(true){

      //Presentación

                                                     41
iniciar();

      presentacion(g);

      //dentro de los niveles del juego. //Game loop 2

      while(minero.getVidas()>0 && (!gameCompleted) ){

      start= System.currentTimeMillis();

     //Muevo el minero

      minero.mover(this.getKeyStates());

      //Compruebo colisiones

       puntosAux = minero.colision(nivel.getTilesColision(),
nivel.getMonstruos(),nivel.getTiles());

      nivel.sumarPuntos(puntosAux);

      minero.animacionInterna();

                                                               42
//Actualizo estado del minero, para comprobar si tiene suelo
debajo y si tiene suelo que se cae actualizar también el suelo

      minero.actualizarEstado(nivel.getTilesColision(),nivel.getTiles());

      nivel.comprobarBarra(); //comprueba si se quedo sin aire

      nivel.actualizarBarra();

      nivel.animarMonstruos();

      nivel.animarTiles();

      if (minero.estaMuerto()){

        animacionMatado(g);

        minero.reiniciar();

        nivel.setNivel(nivel.getNivel(),this);

        minero = nivel.getPersonaje();

      }else if(minero.nivelPasado && (nivel.getNivel())+1
animacionMatado(g);

          nivel.animarNivelPasado(g, this);

          minero.reiniciar();

          nivel.siguienteNivel(this);

          minero = nivel.getPersonaje();

       }else if(minero.nivelPasado && (nivel.getNivel()+1) >=
Nivel.NIVELES){

          animacionMatado(g);

          nivel.animarNivelPasado(g, this);

          gameCompleted = true;

      }

      if(!gameCompleted)

          nivel.hacerScroll(this);

      g.setColor(0,0,0);

      g.fillRect(0, 0, this.getWidth(), this.getHeight());

      nivel.pintar(g,this);

      flushGraphics(0, 0, this.getWidth(), this.getHeight());

                                                                44
try {

            end = System.currentTimeMillis();

            duration = (int)(end - start);

            if (duration < sleepTime){

                Thread.sleep(sleepTime-duration);

                // Thread.sleep(1000);

            }

    } catch (InterruptedException ex) {

            ex.printStackTrace();

    }

}

        //si se completo el juego muestro los créditos

        if(gameCompleted){

            mostrarCreditos(g);

            gameCompleted=false;

        }

                                                         45
}

  }

El entero sleepTime debe ser el tiempo que tarda en ejecutarse un ciclo,
mientras menor sea más rápido se ejecutaran los ciclos y por tanto más
rápido irá el juego. En caso de que el tiempo de ejecución de instrucciones
del ciclo sea menor que sleepTime, el proceso dormirá un tiempo hasta
que el tiempo de ejecución de ese ciclo coincida con sleepTime.

La clase Graphics es la que se encargará de dibujar los gráficos a nivel de
pixeles en la pantalla. Tenemos un objeto g que se relaciona con la
pantalla actual, con el método getGraphics() de GameCanvas que es
heredado a MinerCanvas ya que esta extiende a GameCanvas.

Al dibujar con Graphics realmente se dibuja en una pantalla virtual, y no se
vuelca en la pantalla real hasta que no se usa el método flushGraphics() de
GameCanvas, con esto nos ahorramos que en la pantalla se vaya
dibujando cosas a medida q se ejecutan las instrucciones de dibujado y de
esta forma se dibuja en la pantalla realmente cuando ya esta dibujado
todo.

El método iniciar se encarga de preparar el nivel (crear el nivel, posición
de los elementos, iniciar vidas del personaje, posición, estado, etc.):

  public void iniciar() {

                                                                              46
nivel = new Nivel();

      this.setFullScreenMode(true);

      nivel.setNivel(0,this);

      this.minero = nivel.getPersonaje();

  }

Presentación(Graphics g), es un método creado el cual muestra la
presentación del juego antes de empezar a jugar, en mi caso he decidido
poner un nivel cuyo número de nivel es el 0 que aparece en iniciar(), pero
que no tiene enemigos ni se acaba el aire, ni tiles con animación, ya que
esta fuera de la mina.

 En un principio, iba a poner la presentación como en el juego original,
pero el tamaño de la presentación era demasiado ancho para la pantalla
de un móvil y me pareció buena idea que el personaje se pudiese
controlar con la presentación que ya estaba realizada para que el usuario
pueda ver la presentación completa parecida al juego original con el
scrolling de la pantalla, al mover el personaje.

                                                                        47
24. Pantalla de presentación del juego

Dentro del game loop 2, que es el que controla los siguientes niveles
donde existen enemigos, llaves y tiles animados, realizamos las
operaciones para que nuestro personaje se mueva, colisione con los tiles y
enemigos y compruebe si se ha pasado el nivel y si termino el juego.

Mientras no se quede sin vidas o no nos hayamos pasado el juego no
salimos de este game loop.

6.5 Implementación del salto

Para medir mejor el salto desarrolle en photoshop una imagen en la que
compuse los distintos movimientos en un punto del sprite:

                                                                         48
Los pixeles azules son el desplazamiento por ciclo del salto hacia delante,
los puntos morados son del personaje andando, y los pixeles amarillos son
de la caída.

Para hacer el movimiento del salto tuve en cuenta que el desplazamiento
horizontal es siempre de 2 pixeles por ciclo mientras este en el aire y que
el desplazamiento vertical iba variando cada ciclo. Para solventar este
último problema realice una matriz de enteros en la clase Personaje
indicando cuanto se desplaza en cada ciclo mientras este saltando:

int salto[] = {-4,-4,-3,-3,-2,-2,-1,-1,0,0,1,1,2,2,3,3,4,4}; //Indica cuanto tiene
que avanzar verticalmente en cada ciclo

                                                                               49
Para saber porque he puesto números negativos basta sabe que las
coordenadas en el móvil empieza en x=0 y=0 en la esquina izquierda y
arriba tal como muestra el siguiente gráfico:

X será el eje horizontal e Y el vertical, de manera que si el sprite se tiene
que desplazar hacia arriba le tenemos que sumar un número negativo a su
posición actual y para bajar sumar un número positivo a su posición
actual.

6.6 Implementación de las colisiones

El tema de las colisiones ha sido el más desarrollado ya que aunque MIDP2
dispone de una API que detecta la colisión con tiles y sprites no nos dice
con que tiles ha chocado ni la cara, con lo que opte por desarrollar
métodos de colisión que me dijese con qué objeto choca el personaje y la
cara con la que choca para actuar de una forma u otra en el personaje en
la clase Personaje, ya que actuamos sobre él.

Existen distintos tipos de objetos que al colisionar hay que actuar de una
manera u otra, los hemos agrupado en:

                                                                             50
OBJETOS COLISION

   0.   Nada -              Transparente
   1.   BLOQUE –            Rojo
   2.   SUELO -             Negro
   3.   SUELO QUE SE CAE – Naranja
   4.   Cinta izquierda-     Verde con una I
   5.   LLAVE -             Amarillo
   6.   MUERTE -            PURPURA OSCURO
   7.   Mecanismo -         GRIS
   8.   Cinta derecha-      Verde con una D
   9.   Puerta salida-      Marrón con picaporte amarillo

   El número indica el nº de tile que le corresponde. Entonces, me di
   cuenta de que si cambiaba de orden o si metía mas tiles diferentes no
   funcionaría correctamente, así que utilice un mecanismo para que
   independientemente del gráfico que usase como tile el personaje
   colisionase y supiese con qué tipo de objeto colisiona.

   El mecanismo lo encontré en el tutorial de juegos de plataformas de un
   software llamado Game Maker para hacer videojuegos sin programar:
   http://www.yoyogames.com/make/tutorials

   El mecanismo consistía en desarrollar un conjunto de tiles únicos que
   fuesen de colisión. Los cuales introduje en un fichero gráfico que
   contenía la siguiente imagen:

                             25. Tiles de colisión

   Los colores indicados arriba coinciden con el color de estos tiles en los
   tipos de objetos. Por ejemplo el rojo coincide con el tile nº 1 de la

                                                                           51
imagen de arriba y es rojo, el 0 que representa nada lo genera
automáticamente netBeans y no hay que ponerlo en el fichero.

Primero desarrollamos el escenario con los tiles que no indican el tipo
de objeto sino que son partes del escenario gráfico y tienen tiles
animados:

                     26. Fichero de tiles gráficos del mapa 1

                            27. Primer mapa de tiles

                                                                      52
Después desarrollamos otro mapa de tiles pero con los objetos
colisionables, los cuales no se mostraran al usuario pero son los que se
comprueban cuando colisiona, hay veces que un tile de colisión tiene
impacto sobre un tile gráfico, por ejemplo en las llaves, por lo que
tenemos que pasar el tile de colisión t y el tile de gráficos t2, para saber
con qué tile colisiono:

                            28. Mapa con Tiles de colisión

   Como se observa el posicionamiento de los elementos del mapa de
   colisión es igual que el del mapa de tiles gráficos, la diferencia es que el
   mapa de tiles gráficos tiene muchos más tiles diferentes. Este nuevo
   mapa nos ayudará a encontrar con qué tipo de objeto colisionamos
   fácilmente, algo que no se podría hacer fácilmente para el anterior
   mapa, por ejemplo si queremos saber si colisionamos con una llave, ya
   que existen varios tiles asociado a su animación y cada mapa puede
   tener sus propios tiles y ordenamiento de ellos en el fichero gráfico,
   haciendo que el número de tipo que le corresponde varié de un fichero

                                                                               53
a otro, lo cual no ocurre con esta ultima técnica de colocar un mapa de
colisiones con tiles únicos por cada tipo de elemento.

Por último en el editor de escenarios (scene), ponemos este mapa de
colisión por detrás del fondo, de manera que la lo que nos queda
visualmente no aparece el mapa de colisión aunque si se usa en el
código para comprobar las colisiones:

                       29. Composición del escenario

                                                                      54
30. Colocación de las capas, mientras menor Z más hacia afuera esta el sprite o el TiledLayer
    Como se observa en la imagen superior el mapa de colisión lo hemos
    colocado detrás del todo y no se ve.

Para aprovechar el mayor rendimiento en vez de comprobar si el
personaje colisión con alguno de la gran cantidad de tiles que existe en el
escenario, comprobamos los que están más cercanos. En la siguiente
imagen se muestra cuales tiles del mapa se comprobara si colisiona con el
personaje, indicados con rectángulos:

                                                                                                55
31. Lugares del mapa donde se comprobara si hubo colisión

El cuadrado con líneas blancas y negras, corresponde al tamaño del sprite.

matrizEspacio es una matriz con 2 dimensiones, la primera tendrá de
tamaño del número de tiles horizontales a cubrir en la detección de
colisiones y la otra dimensión el tamaño del número de tiles verticales. El
número de tiles de esto se calcula teniendo en cuenta el número de tiles
que ocupa el personaje, con el siguiente método:

   private int[][] tilesCuadrado(){

      int x = sp.getWidth()/8;

      int y = sp.getHeight()/8;

      x = x+2;

      y++;

                                                                          56
return new int[x][y];

  }

De esta forma comprobamos las colisiones, el tipo que colisionamos, la
cara y si chocamos con un enemigo:

int colision(TiledLayer t, IMonstruo [] monstruos,TiledLayer t2){

      int puntos = 0;

    //PRIMERO MIRO LA COLISION CON LOS TILES
///////////////////////////////

      //Nos dara el tile en el que esta el pixel superior izquierdo del minero

      int tilex = conseguirTilex(t);

      int tiley = conseguirTiley(t);

      //Guarda el numero de tile x e y de la matriz que se está comprobando

      int xaux=0;

      int yaux=0;

      int cara = 0; //Cara 0 -> aun no inicializada

      //POSIBLES VALORES DE CARAS:

      //1 -> arriba

                                                                             57
//2 -> lado

//3 -> abajo

//Tipo de tile con el que colisiona. Si vale -1 significa que no colisiono

int tipoT = -1;

int tipoAux = -1;

int caraAux = 0;

for(int i = 0; i < matrizEspacio.length; i++){

  for(int j = 0; j< matrizEspacio[i].length;j++){

     if(tilex+i < t.getColumns() && tiley +j< t.getRows() ){

       tipoT = tipoColision(t,tilex + i, tiley+j);

       if(tipoT != -1){

         xaux = tilex + i;

         yaux = tiley+j;

         cara = encontrarCara(t,xaux,yaux);

         if(tipoT == this.LLAVE)

              puntos = 100;

         //si choca con alguna cara

         if(cara!=0)
                                                                         58
{

                    tratarColision(tipoT,cara,xaux,yaux, t,t2);

                }

            }

        }

    }

}

if(monstruos != null){

//MIRO A VER SI SE CHOCA CON ALGUN ENEMIGO

for(int i = 0; i < monstruos.length; i++){

    if(sp.collidesWith(monstruos[i].getSprite(), false)){

        vidas--;

        this.muerto=true;

    }

}

}
                                                                  59
return puntos;

  }

“collidesWith(Sprite sp, boolean b)“ de la clase Sprite nos permite
comprobar si un sprite colisiona con otro, lo que nos viene perfecto para
comprobar la colisión con los enemigos. El boolean b si es cierto se
comprueba la colisión a nivel de pixel de la figura interior del sprite.

En caso de que colisione con un enemigo el personaje pasara al estado de
muerto y tendrá 1 vida menos, en el game loop justo antes de dibujar se
comprobara si el personaje ha muerto, en el caso en que este muerto se
reinicia el nivel.

Para comprobar las colisiones de un sprite con los tiles dado que no
tenemos una función concreta que nos diga en qué posición colisionamos
usamos el siguiente algoritmo:

                                                                            60
Los sprites son todos rectangulares, pero la figura descrita dentro de él
generalmente es irregular y existe casos en que un cuadrado no daría la
precisión adecuada:

                            32. Precisión en colisiones
En la imagen de ejemplo se puede comprobar que un programa detector
de colisiones daría cierto en los 2 casos aunque en el caso del cuadrado no
existiría colisión real solo en el caso de los círculos.

En esta otra imagen se puede comprobar que el rectángulo es mejor
detector de colisiones que los círculos.

Se podría comprobar las colisiones a nivel de pixel, pero el tiempo de
procesamiento sería muy grande, así que me decanté por usar el
rectángulo.

El algoritmo para calcular la colisión con 2 rectángulos en un sistema de
coordenadas X e Y es sencillo.

Primero indicamos las variables usadas:

                                                                            61
W1 indica la coordenada X de los pixeles izquierdo del sprite, X1 indica la
coordenada X de los pixeles derecho del sprite.

W2 indica la coordenada X de los pixeles izquierdo del sprite, X2 indica la
coordenada X de los pixeles derecho del sprite.

H1 indica la coordenada Y de los pixeles inferior del sprite, Y1 indica la
coordenada Y de los pixeles superiores.

H2 indica la coordenada Y de los pixeles inferior del sprite, Y2 indica la
coordenada Y de los pixeles superiores.

Para que exista colisión en la coordenada X, se debe cumplir:

W1 >X2 y X1 < W2.

Al igual paraqué exista colisión en la coordenada Y, se debe cumplir:

H1>Y2 y Y1 < H2

Si se cumple que existe colisión en la coordenada X y en la coordenada Y
entonces el sprite colisiona, cumpliéndose:

W1 >X2 y X1 < W2 y H1>Y2 y Y1 < H2

                                                                             62
33. Imagen explicativa de la colisión

Todo este algoritmo esta implementado en el método tipoColision:

private int tipoColision(TiledLayer t,int tilex, int tiley)

  {

      int tipo = t.getCell(tilex,tiley);

      if(tipo != 0){ //Si es distinto de 0 hay colision!

         //donde se encuentra el pixel esquina superior izquierda

        int xpixelT = tilex*t.getCellWidth() + t.getX();

                                                                      63
int ypixelT = tiley*t.getCellHeight() + t.getY();

      if((sp.getX() < xpixelT + t.getCellWidth()) && (sp.getX() +
sp.getWidth() > xpixelT) &&

        (sp.getY() < ypixelT + t.getCellHeight() && (sp.getY() +
sp.getHeight() > ypixelT)))

            return tipo;

      }

      return -1;

  }

Tilex y tiley es la posición en tiles en el mapa a comprobar.

El método getCell(int x, int y) de tiledLayer nos da el número del tile en la
posición x e y tiles del mapa de tiles, es decir el tipo de tile en esa posición.

getX() y getY() de TiledLayer nos devuelve la posición del tiledLayer en el
mapa.

getCellWidth() el ancho en pixeles de un tile.

getCellHeight() la altura en pixeles de un tile.

                                                                              64
Para comprobar la cara del sprite con la que choca he desarrollado el
método, encontrarCara. La colisión con la cara tiene en cuenta la posición
anterior del personaje antes de chocar, después en el método
tratarColision se comprueba si se ha chocado pero antes buscamos con
qué cara colisiona.

private int encontrarCara(TiledLayer t, int xtile, int ytile){

    //Tengo que encontrar la cara con la que golpeo primero

    int cara = 0; //0 si no golpea con nada

    //donde se encuentra el pixel esquina superior izquierda

    int xpixelT = xtile*t.getCellWidth() + t.getX();

    int ypixelT = ytile*t.getCellHeight() + t.getY();

    int posxAnterior = sp.getX() - ultimodx;

    int posyAnterior = sp.getY() - ultimody;

    if((posxAnterior < xpixelT+t.getCellWidth()) &&

           (posxAnterior + sp.getWidth() > xpixelT)){

       if(posyAnterior + sp.getHeight() - 1 < ypixelT){

           cara = 1; //es la cara de arriba

       }

                                                                         65
También puede leer