Mostrando entradas con la etiqueta android. Mostrar todas las entradas
Mostrando entradas con la etiqueta android. Mostrar todas las entradas

Jugar mientras conduces ES POSIBLE

Tanto cacharrito, tanto Internet de las cosas, tanto móvil, tablet, reloj, gafas, pulsera, ¡tanta leche!... y oye... ¡¡¡que KITT, el coche fantástico, sigue sin existir!!!.

El glamour y chulería de David Hasselhoff van aparte, practica todos los días frente al espejo y lo conseguirás. ¡Tú puedes!

"Smart cars"

Lo cierto es que se está trabajando en ello, pero claro, no se tarda lo mismo en hacer un coche que una pulsera. El camino se está marcando: BMW y Chevrolet apuestan por los iPhone y su Siri Eyes Free, y parece que ya ha salido algún modelo y se esperan más durante este mismo año. Otros como Ford apuestan por un sistema Sync de Microsoft, sobre el cual tengo unas ganas enormes por ver cómo reproducirán de forma sonora los pantallazos azules (apuesto a que sonará como los pitidos de carga de juegos del ZX Spectrum).

Audi parece hoy por hoy la más atrevida, y apuesta por su propia pantalla Virtual Cockpit integrada en lugar del clásico cuadro de mandos, y apuesta por la estandarización de Android y se alía con Google y otros fabricantes como General Motors, Honda y Hyundai para crear la Open Automotive Alliance.

En fin, aparentemente la baraja está lista y sólo queda echar las cartas. La referencia por ahora es el CES2014, que es donde se han presentado todas estas novedades de los coches, y según eso aparentemente este mismo año se empezarán a ver cosillas en la calle. De hecho, si comparamos las fotos que se están mostrando ahora de los cuadros de mandos de Audi con el de KITT la verdad es que por ahí ya vamos ganando.

Audi Virtual Cockpit
Más Audi, ¡leche!
KITT, vintage a tope pero... ¡más mono!

¿Y qué harán estos smart cars, o como vayan a llamarlos?. Navegador GPS, claro. ¿Y aparte?... ayudas para aparcar, que el coche te lea los wasap y correos, ayudas a la conducción... ¡BOBADAS!. Vale, seguro que el coche conduce mejor que mucha gente pero ¿de verdad te vas a fiar hoy por hoy de lo que conduzca?.

A mi todo eso me da igual. Yo lo único que quiero es que ya que tiene tanto cacharro y tanta gaita, cuando tenga un viaje en el que vaya yo solo conduciendo no tenga que estar aburrido oyendo música o cualquier chorrada que pongan en la radio. Lo que yo quiero es que... ¡PUEDA JUGAR!.

Sin matarme al hacerlo, claro.


¿Cómo puedo jugar sin usar las manos ni apartar la vista?

Esta es la pregunta clave: ¿es posible?. Previsiblemente, al menos cuando la cosa esté lo bastante avanzada, el interfaz con el smart car tiene que ser fundamentalmente a través de la voz. Cada vez que quieras que el coche haga algo, le hablas. Para que reconozca que quieres hablar con él, supongo que al principio seguramente tengas que pulsar un botón o una palanca del volante, pero lo normal es que llegue un momento en que el coche esté continuamente activo esperando a que le digas algo, y que reaccione ante una palabra clave: su nombre. Incluso, se podría poner en "modo conductor solitario" y que reaccionase ante cualquier cosa que le dijeras sin tener que decir su nombre.

Se ha trabajado mucho en reconocimiento de voz últimamente. Antes en inglés todavía, pero en español no reconocía ni papa. Ahora con los avances del Siri de Apple y el Google Now, más otros "outsiders" como Sherpa (que además es español), el reconocimiento de voz está mejorando cada vez más. Ya se puede hablar con el móvil y mientras lo hagas con cierta calma, funciona bastante bien. Cualquiera podéis hacer la prueba con vuestro smartphone, si no lo habéis probado aún. Creo que todavía le falta un puntito para que sea más cómodo, para poder hablar con menos cuidado y que te siga entendiendo, pero no me cabe duda de que se conseguirá.

El coche, por supuesto, también responderá con la voz. La síntesis de voz también funciona muy bien actualmente. Cualquiera que hayáis usado un GPS en vuestro móvil lo habréis visto. Existen otros motores de síntesis de voz más avanzados, que a menudo son de pago. El reto en este caso es conseguir que la voz tenga alma. Que sea capaz de entonar un poco, no sólo leer. ¡Diablos, al menos como lo hacía KITT, que tampoco era el alma de la fiesta!

Entonces, de lo que se trataría es de encontrar un tipo de juego que se pueda jugar sólo con la voz, hablando con el coche. Y que no sea el "veo veo", vaya.

El caso es que existe un tipo de juegos que encaja perfectamente con esta forma de comunicación: las aventuras conversacionales.


Aventuras conversacionales

Sin gráficos: Fotopía

Las aventuras conversacionales, o interactive fiction (IF) como se las conoce en inglés, son un tipo de juego antiiiiiiiiiiiiguo. La primera se considera que es Adventure, data del año 1975 y se programó en Fortran en un PDP-10. O sea, tela. Sin embargo, vamos a ver cómo su simplicidad y su falta (o no necesidad) de gráficos juegan muy en su favor en este caso.

Distribución típica, con gráficos arriba: Alien

En una aventura conversacional, se te cuenta una historia y se te pone en situación y describe tu localización actual mediante texto. Entonces tú, el jugador, escribes también por texto y en lenguaje "natural" lo que quieres hacer. El juego devuelve el resultado de tu acción otra vez como texto, y así sucesivamente, de forma que se crea una conversación entre el juego y tú. La historia va evolucionando con lo que vas haciendo, y se te van presentando retos y puzzles a resolver.

de computeremuzone.com
Puede que te suenen porque en España tuvieron su época dorada en los años 80-90, cuando Aventuras AD lanzó para los ordenadores de 8 bits juegos como La aventura original, Don Quijote, El Jabato o La Diosa de Cozumel. Incluso, por entonces llegaron a España varios juegos en inglés, especialmente El Hobbit, y que obligaron a muchos jóvenes de la época a tirar de diccionario. Aunque ya por entonces la mayor parte de los juegos tenían gráficos descriptivos de las localidades, lo cierto es que dichos gráficos eran normalmente superfluos y no afectaban al desarrollo del juego, y su objetivo fundamentalmente es hacer los juegos más atractivos a la vista (cosa que nos importa poco mientras conducimos).


Este tipo de juegos, evidentemente, encaja perfectamente con un interfaz de voz. Tú dices lo que quieres hacer, el coche responde. Curva cerrada a la derecha, te callas y te concentras. Vuelves al juego, dices lo siguiente... te puedes tirar un montón de tiempo así. Y creo que a la vez, aparentemente no es tan inmersivo como para que pierdas la concentración en la conducción.

Y además... ¡son un tipo de juegos muy divertidos! (incluso si no los comparamos sólo con el veo-veo).

Esta sería una hipotética transcripción de una conversación entre KITT (obviamente llamaríamos así a nuestro coche) y tú, que dé paso a una sesión de jugar una aventura:


KITT: Buenos días, Andrés

Andrés (reemplázalo con tu nombre para disfrutarlo más): Hola, KITT

K: ¿Dónde vamos?

A: Vamos a casa

K: ¿A casa, a la calle Ríos Rosas?

A: Sí, eso es

(KITT programa el GPS y tú mientras arrancas y te pones en camino)

A: KITT, vamos a jugar a Olvido mortal

K: Cargando Olvido mortal. Continuamos la partida que dejaste ayer. ¿Correcto?

A: Sí

KITT: Oficinas
Estás en una especie de oficinas.
No ves ningún cartel que te indique qué lugar es este. La cola se extiende por la alargada localidad, enorme. Por detrás, una pared te impide ver dónde acaba. La fila de gente continúa por una puerta abierta en la pared.
En el otro sentido, las cabezas te impiden ver qué hay al principio de la cola.

La mujer de delante en la cola parece ser la única persona que te presta algo de atención.


(un chalao se te cruza en ese momento y te centras en lo tuyo)

A: Perdona, KITT, ¿puedes repetir?

K: Oficinas.......... (y repite toda la descripción, ¡más majo!)

A: Resumen

K: Despertaste en la cola sin recordar quién eras ni dónde estabas.

A: Inventario

K: Llevas: una cartera (que está cerrada)

A: Abre la cartera

K: Abres la cartera, descubriendo un carnet de identidad y una foto.

A: Mira el carnet

K: Es un carnet de identidad normal y corriente. La foto del carnet está un poco difuminada, pero se ve lo suficiente.

"¿Es posible que ese sea yo?. Desde luego, la cara me resulta familiar, pero no soy siquiera capaz de asegurar tajantemente que sea la mía."


(...)
(y así pasa el tiempo y cuando te quieres dar tiempo estás ya en casa... ¡y no quieres dejar de jugar!)



¿Qué tal, te convence?. ¡¡¡A mi sí!!!

Otra buena noticia es que muchos de estos juegos son multi-plataforma y se ejecutan sobre una máquina virtual. O dicho de otra forma: es muy muy fácil adaptar un intérprete de estos juegos para que se ejecute en un coche y se juegue con la voz. Y automáticamente, en cuanto tengas hecho el intérprete, tienes disponibles cientos, miles de juegos, listos para jugar.

En español, el mejor sitio donde encontrar juegos es la web del CAAD, el sitio donde se reúnen todos los "chalaos" de este tipo de juegos y aúnan esfuerzos alrededor de la aventura. Una de las grandes ventajas que tienen estos juegos, además, es que casi cualquiera puede programar uno. No hace falta ser programador, ni tampoco saber dibujar ni componer música. Esto ha hecho que se cree una comunidad alrededor de ellos y que se sigan programando juegos. En inglés, por otra parte, la comunidad es aún más activa y para descargar juegos tenemos el Interactive Fiction Archive.

Si queréis probar con alguno de estos juegos, ¡qué demonios!. ¡Prueba alguno de los que he hecho yo! Sí, así a lo tonto y mientras hablaba de "esos chalaos" en tercera persona, os metía de tapadillo mis juegos (hechos hace ya un buen montón de años, en el 2001, ahí es ná): Olvido mortal, que ya habéis probado un poco con KITT pero podéis jugar online aquí, y Akbarr.

Forma original en forma de libro: Akbarr


Conclusión

Esto no es más que elucubrar pero, ¿por qué no?. Está todo ahí: los coches ya produciéndose integrados con tecnologías móviles como Android e iPhone, los motores de reconocimiento y síntesis de voz a un puntito de ser cómodos y molones, justo ese puntito de más que daría el interés por el mercado de los coches... y las aventuras conversacionales ahí, listas para que las juguemos charlando con nuestro coche mientras hacemos un viaje.

¿Y vosotros, qué pensáis de todo esto?...

¿Y tú, KITT?. ¿Te apetece que juguemos?.


Haciendo un juego en Android: lecciones aprendidas (2)

Después del primer capítulo que publiqué hace unas semanas, ya tenemos lo básico para hacer un juego en Android "a pelo". ¡Pero no nos conformamos con eso! Hoy contaré otras cosillas más que fui añadiendo a mi librería personal para el juego según iba avanzando.

Componentes gráficos

Para los que hemos trabajado con interfaces de ventanas, el diseño basado en componentes gráficos resulta muy natural. ¿Por qué no aplicarlo también a un juego?.

La idea es muy sencilla: hacer que el código de cada componente no tenga que preocuparse de coordenadas globales, ni de lo que ocurre en el resto del juego, sino que vive "en su propio mundo" y preocupado de sus cosas. Orientación a objetos pura, vaya. Así, la pantalla se va formando a base de componentes, unos dentro de otros, que acaban conformando todo lo que hay en el juego. Cada uno tiene su propia dinámica, y luego pueden reaccionar ante lo que hagan los otros.

Todas estas librerías tradicionales de componentes de ventanas, como las MVC del Visual C++, o la del Borland C++, o incluso las del más moderno SWT suelen tener un problema gordo en su diseño: abusan mucho de las subclases. Se puso de moda diseñar esto así, y como documentación de la librería aparecía, tachán!, ¡la jerarquía de clases!. O sea, todo el diseño estaba hecho en forma de jerarquía de subclasificación.

El caso es que a mi las subclases en general me dan un poco de urticaria. Los interfaces son mucho más limpios. Las subclases me gustan para reutilizar implementaciones por defecto o sencillas de los interfaces, pero poco más. Así que en lugar de hacer una jerarquía de clases como las de toda la vida (curiosamente Swing, con todo lo que se le ha criticado, está mucho mejor diseñada que todas las demás), me dediqué a darle unas vueltas más (y liar un poquito el tema, ya puestos).

¿Qué necesita cada uno de estos componentes?. Según vimos en la entrada anterior, lo mínimo que necesita cualquier entidad independiente del juego es:
  • Que sea capaz de reaccionar a eventos
  • Que sea capaz de actualizarse sola por cada unidad de tiempo
  • Que sea capaz de dibujarse
Además de esto, nuestros componentes gráficos necesitarán:
  • Una posición relativa a su componente padre
  • Un tamaño
Y por supuesto, necesitaremos entidades contenedoras, a las que podamos meter otras entidades dentro de forma relativa.

Así que hice un interfaz GameEntity para lo básico que tienen que tener todas las entidades de cualquier juego (los tres primeros puntos), y reservé dos interfaces para los otros dos: un Positionable y un Measurable. ¿Por qué usar interfaces para estos dos en lugar de beans?. Porque me puede dar más juego. Por supuesto, creo implementaciones beans que implementen esos interfaces, y un DelegateComponent que cree un componente a partir de una composición de objetos que implementen cada interfaz (y que no tienen por qué ser objetos distintos).

Una vez que te acostumbras a esta forma de trabajar, resulta comodísima, y sobre todo, muy potente. Este es el diseño resultante:




Animaciones, efectos y el estado

Cada objeto normalmente tendrá su estado e irá cambiando según las cosas que le ocurran. Eso ya dependerá de cada entidad. Sin embargo, hay algo que también es muy interesante facilitar, que son las animaciones y efectos. Aunque pueda confundirse, lo cierto es que estos se gestionan mucho mejor si se separan un poco del propio estado del objeto.

Por ejemplo, un personaje puede estar caminando. Su estado es "caminando". Sin que el estado cambie demasiado, se estará moviendo hacia la derecha. Y habrá una animación de caminar que irá cambiando sola cada X frames. Podríamos gestionar todo esto de forma explícita dentro de cada objeto, pero si lo facilitamos para que se declare desde el principio como funciona, nos evitaremos el tener que gestionar cosas incómodas como cuál es el frame actual que se debe mostrar.

Para eso, creé una clase AnimatedComponent, que decora cualquier otro componente. A este componente se le registrarán una serie de estados de transiciones o animaciones posibles, representadas con el interfaz Transition. Al registrar cada transición se indica cómo funciona: qué propiedades modificará, cada cuánto tiempo y qué ocurrirá cuando acabe (¿será cíclica?, ¿se quedará en el estado en el que estaba?, ¿desaparecerá el objeto?). Estas transiciones son las que se ocupan de hacer efectos y transiciones sin que el objeto tenga por qué preocuparse mucho por ello.

Como ejemplos de transiciones están las animaciones de gráficos, movimiento, efectos de "fade", cortinillas... A pesar del tinglado anterior del diseño de componentes por interfaces separados, lo cierto es que en la práctica casi todos los objetos utilizarán un bean para la posición. También bastantes para el tamaño, aunque no tantos, ya que muchas veces puede depender del tamaño de su bitmap o de su texto, por ejemplo. Por supuesto, también las animaciones es lógico que vayan con una propiedad explícita... en definitiva, una de las transiciones más sencillas que podemos hacer es que automáticamente se vaya incrementando o decrementando el valor de una propiedad del componente. De aquí surgió la clase BeanPropertyTransition. Para controlar de forma independiente a qué ritmo se va modificando el valor de la propiedad, se hace que utilice un interfaz IntPropertyChange, con una implementación sencilla que aumente el valor de la propiedad de forma lineal, es decir, de forma constante en el tiempo.

Así quedó el diseño:


Agrupando objetos "globales"

En las primeras versiones del juego, los constructores de los distintos objetos cada vez eran más grandes. Había una serie de objetos, digamos, prácticamente globales, que se podían utilizar casi en cualquier sitio.

Dos de ellos son clases que creé para encapsular, facilitar y/o mejorar el rendimiento de la reproducción de sonido: SoundManager para efectos de sonido, y Jukebox para música. A ellos se les suma el necesario Context de Android, con el que se cargan todos los recursos, y que face falta básicamente en... todos los sitios donde haga falta un recurso. Y otros que iban apareciendo y desapareciendo según se iba refinando el diseño, como por ejemplo una clase que facilita la carga de Bitmaps.

La solución en este caso es muy clara, encapsular todos estos objetos, que además son genéricos y valen para cualquier juego, en una sola clase GameContext, que permita acceder a ellos. Así, sólo será este objeto el que habrá que pasar a todos los demás (junto a otros objetos del propio juego que potencialmente también harán falta). Además, si en algún momento aparece otro objeto del sistema que nos venga bien de forma global, se puede añadir también sin tener que tocar todas las demás clases para que se lo pasen de unas a otras.

Esto parece una tontería, pero lo cierto es que si no se tiene un poco de cuidado, en un juego es muy fácil acabar con miles de objetitos que se van pasando a troche y moche de unos a otros, y eso se convierte en un caos. También hay que tener mucho cuidado de no mezclar churras con merinas, y no encapsular dentro del mismo objeto todo lo global que pueda necesitar el juego. Una cosa son estos objetos que pueden hacer falta en cualquier juego y son, digamos, del sistema y sus recursos, y otra muy distinta meter también por ejemplo los objetos que controlen la dinámica del juego concreto.

En nuestro caso, este es el diseño que quedó:



Acabando, que es gerundio

¡Buah, menudo coñazo de serie que me he marcao! Todavía el primer capítulo tenía su aquel, pero en este me he metido más bien en detalles de diseño e imagino que ha quedado bastante espeso. Y no he puesto chistes ni chorradinas ni ná. Así que nadie estará leyendo esto ya, ¡snif!.

El mensaje fundamental de todo esto es el primero que di: si estáis dudando en poneros o no a hacer un juego con Android, no lo dudeis: hacedlo. Es muy agradecido, con poco que hagáis van saliendo cosas. La librería de Android es genial, da muchas facilidades. Es más, yo hay cosas en las que me he complicado la vida porque he querido, porque lo cierto es que creo que algunas de las cosas que he hecho yo están ya en la propia librería estándar de Android. Y eso por no hablar del resto de librerías que existen para hacer juegos. Simplemente, me apeteció hacerlo así. Y ojo, mientras refinaba un poco la librería me dio tiempo a hacer otro juego, un Reversi (este ya no lo voy a publicar, porque Reversis hay montones y seguro que juegan mejor que el mío, que es un pobre patán...).

El secreto de todo esto de hacer juegos para móviles, lo que lo hace genial, es que es pequeño. No necesitas dedicar meses y meses de tu vida para hacer un juego. En una tarde ya ves avances. Cada tarde que te pongas haces algo, consigues algo nuevo. Es muy gratificante. Estoy convencido de que los juegos pequeños tienen su espacio, que no todo tienen que ser grandes producciones. Dan más pie a la imaginación, a la innovación, a atreverse a hacer cosas que pensabas que no iban a salir... en definitiva, ¿a qué estás esperando?, ¡¡¡ponte ya a hacer tu juego, leche!!!.



Bola extra

Has intentado entender el artículo. Realmente lo has intentado. Te lo has leído de principio a fin, has imprimido los diagramas en grande para seguir las flechitas, has buscado por ahí a ver qué leche es esa mierda de los componentes gráficos... y eso sólo te ha desorientado más aún. Finalmente, has llegado a una conclusión ineludible: ¡no hay dios que entienda este artículo!

Pues bien, aprovechando que hoy es el "día Somos", que propone darle la vuelta al mundo, he apoyado la causa y he hecho una nueva versión del mismo en la que le he dado la vuelta por completo. Jamás la Informática había sido tan sencilla, jamás algo complejo se había visto de una forma tan clara. Jamás había sido tan fácil conseguir que cualquier no iniciado puede comprenderlo con facilidad.

No te pierdas la versión revisada del artículo. De repente verás la luz y lo comprenderás en toda su extensión.

Haciendo un juego en Android: lecciones aprendidas (1)

Uno de los principales motivos por los que hace unos meses me puse con el desarrollo del West Bank es porque tenía ganas de empezar a aprender algo de Android. Android te permite algo que ya se había perdido un poco, y es que puedas hacer una aplicación más o menos pequeña, pero que a la vez esa aplicación sea publicable e incluso sea útil. Y en algunos casos, hasta te haga ganar dinero. Para los que no tenemos casi tiempo libre eso es genial, claro. En este artículo cuento un poco algunas de las cosas que me fui encontrando y lecciones aprendidas..

Hacer juegos con Android es muy fácil. Incluso sin librerías

Esta es seguramente la conclusión más importante que he sacado, algo que por otra parte ya me imaginaba. En mi caso, comencé primero buscando un poco alguna librería / framework / engine de desarrollo de juegos que me facilitara la vida. La idea es que fuera una librería sencillita y enfocada al 2D, nada de polígonos ni historias. La primera que vi fue Rokon, que tenía buena pinta y encajaba en lo que buscaba, pero el autor recomendaba no usarla (imagino que acabó cansado de responder emails de gente haciéndole preguntas). Como el objetivo era complicarse la vida lo menos posible y hacer el juego rápido, la descarté.

Entonces miré libgdx, que es una librería multiplataforma. Eso es una ventaja evidente, pero a la vez para este caso también es una desventaja, porque el objetivo con el que empecé era aprender algo de Android. Cuando me di cuenta de esto, y llevándome eso a descartar sin apenas mirarlas otras librerías con muy buena pinta como AndEngine, pensé: "¿Y si lo hago directamente usando las librerías nativas de Android?".

Buscando por Internet encontré este buen tutorial de introducción de JavaCodeGeeks. Y sólo mirándolo por encima ya vi que Android de serie te da enormes facilidades para manejar gráficos, sonidos y eventos táctiles. Por otra parte, para el juego que nos ocupa no iba a necesitar ningún tipo de aceleración gráfica OpenGL ni otras mandangas de optimizaciones. Así que decidido: no usaría ninguna librería, haría la mía propia basada en la librería estándar de Android.

Gráficos en pantallas con distintas resoluciones

Esto ha sido seguramente lo que más quebraderos de cabeza me ha dado. Y lo cierto es que si lo entiendes bien y no te metes en líos, tampoco es algo que tenga por qué darte problemas. En Android a priori no sabes cuál es el tamaño de la pantalla, ni tampoco sus proporciones (screen ratio), y tienes que intentar que en todas ellas el juego se vea lo mejor posible.

Esto implica redimensionamiento de tres elementos: los gráficos, las posiciones en los que pintas los gráficos y los puntos en los que se detectan los eventos táctiles. De primeras solucioné esto creando una clase (más bien cutre) PointTranslator, con un objeto que le pasaba a todos los demás objetos del juego y al que llamaba cada vez que quería traducir una posición o pintar un bitmap.

Para solucionar el problema de las proporciones de pantalla puse unas franjas negras en la parte que sobrara de la pantalla. Otra solución hubiera sido alargar el bitmap, pero prefería no distorsionar las imágenes. Mi resolución estaba clara, como utilizaba directamente los gráficos del ZX Spectrum, la suya sería la resolución que iba a usar: 256x192 (con proporción 3:4).

Cuando ya tenía algo que pintaba los gráficos y detectaba las pulsaciones en su sitio, me di cuenta de otro problema: según el móvil en el que cargabas los bitmaps, ¡el propio bitmap podía tener un tamaño diferente al real!. Por lo que vi, esto dependía de otro parámetro: la densidad. Esto afecta sobre todo a la carga de sprites. Una de las típicas técnicas en los juegos es meter todos los gráficos de un personaje en un solo fichero. Al dibujar uno de ellos, se dibuja sólo la parte del gráfico que corresponda. Al no tener el bitmap el tamaño que se suponía iba a tener, esto se desmadraba. Ale, otra chapuza a meter al "soluciones todo-en-uno" PointTranslator.

Otro problema que tuve con esto fue el del redondeo. Normalmente los bitmaps se cargaban en su tamaño o en un tamaño múltiplo. Pero, ¡ay!, no siempre es así. Concretamente, el Nexus 7 carga los bitmaps en una escala extraña. Esto hace que en bitmaps con muchos gráficos, el redondeo fuera importante y no se cargaran bien. Concretamente, el problema era muy evidente en las fuentes bitmap que usaba para escribir los textos. Vuelvo a tocar (¡cómo no!) ese maravilloso PointTranslator para que use coma flotante para estas cosas y listo.

Lo cierto es que estos dos últimos problemas: carga de bitmaps y redondeo no tienen por qué existir. Los cuento porque creo que puede ser interesante saberlo, pero la verdad es que desde el principio fue por una metedura de pata mía. Como todo el proyecto lo he ido haciendo sobre la marcha y sin documentarme debidamente, ya que lo más importante era ir avanzando y obtener cosas funcionando lo más rápido posible (doctor, ¿me habré hecho "ágil"?), cuando probé a meter el primer gráfico lo hice en la carpeta "res\drawable-mdpi". En mi ignorancia, pensaba que estas carpetas ldpi, mdpi, hdpi servirían para cargar gráficos más o menos grandes según la resolución de tu dispositivo, y que si sólo encontraba un gráfico en una carpeta cargaría ese y ya está. Craso error. Lo primero es que no es eso lo que significan esas carpetas, no funcionan según la resolución de pantalla (en cuanto a número de pixels), sino en cuanto a la densidad, es decir, los puntos por pulgada del dispositivo. Es decir, el objetivo de usar esto es, por ejemplo, que se vea más o menos igual de grande (en cuanto a tamaño físico) un gráfico cargado en un tablet que cargado en un móvil con resolución alta o en otro con resolución baja. En definitiva, nada que a priori nos interese ni lo más mínimo cuando estamos haciendo un juego. Para más información, tenéis el artículo oficial sobre el tema (un poco ladrillete, pero es que esto es así...). ¿La solución a esto?. Muy fácil, una de estas:

  • Meter los gráficos en una carpeta drawable-nodpi
  • Si queremos cargar diferentes gráficos según la resolución de pantalla, usar carpetas de recursos drawable que dependan del tamaño en píxeles: small, normal, large, xlarge
  • Meter los gráficos como assets en lugar de como resources. Esto, además, nos permite componer de forma dinámica el nombre del bitmap a cargar, o de su carpeta

Esto último es por lo que me he decantado yo, ya que quiero cargar distintos gráficos según la configuración del juego: versión ZX Spectrum, o nueva versión con gráficos HD... ¡pronto en sus kioskos!.

De hecho, esto último me ocasiona un nuevo problema: los gráficos del juego tendrán distintos tamaños, posiciones y hasta resoluciones diferentes según su configuración. Esto me ha llevado a hacer una refactorización, eliminando alguna chapucilla y mejorando el diseño de las clases para facilitar esto. Y sí, tuve que tomar la difícil decisión de eliminar mi clase-bombero... es decir... el PointTranslator ha muerto (¡viva el PointTranslator!).

Por lo pronto, en lugar de redimensionar todos los puntos sobre la marcha dentro del propio juego, ahora lo que hago es pintar todo en un buffer intermedio, que tiene el tamaño exacto de la resolución del juego. Al terminar de dibujar todo, se pinta redimensionado en el buffer de pantalla. Para encapsular todo esto he creado una clase Camera. Cada vez que el controlador del juego quiere pedir a los objetos que se dibujen, llama a la cámara para que devuelva el Canvas (la clase estándar Android donde se pintan cosas) bien configurado. Al terminar todos de dibujar, vuelve a llamarle para que lo plasme. De esta forma, toda la complejidad del proceso se queda en las clases genéricas de mi librería, y las clases específicas del juego se despreocupan totalmente de los problemas de resolución, ellas trabajan siempre con las dimensiones que marque el juego y ya está.

Todavía me he encontrado con un problema, que ha sido a la hora de traducir las posiciones de los eventos táctiles. Para estas cosas, Android tiene una clase, MotionEvent, que la verdad es que me gusta bastante tal cual está y por tanto no tenía intención de crear otra nueva para lo mismo. Pues bien, resulta que la clase MotionEvent no permite reescalar ni modificar sus posiciones. Bueno, a partir de la versión 11 del API sí, pero quiero que el juego funcione en versiones de Android más antiguas. Lo solucioné creando mi propia clase GameMotionEvent, que utiliza el patrón de diseño delegate para encapsular la clase anterior, proporcionando un interfaz igual y llamando en cada método al equivalente a la anterior, haciendo las pertinentes traducciones de puntos cuando hagan falta a través de la clase Camera.

El bucle principal: con cuatro cosillas lo haces, ¡pero cuidado!

Como bien sabrás si has hecho un juego alguna vez, el bucle principal (el game loop) supone la estructura fundamental de cualquier juego. Es un bucle "infinito" de tres pasos: procesar entrada, actualizar estado de los objetos, dibujarlos (aunque en realidad lo de procesar la entrada no tiene por qué ir estrictamente en ese orden y se puede hacer más bien en forma de eventos). Y hacerlo además de forma que cada ciclo se haga en el mismo tiempo, gestionando condiciones como que si tardamos más tiempo de lo que deberíamos en hacer un ciclo, nos podamos saltar pasos de dibujar para que todo vaya lo más suave posible, y si tardamos menos, esperemos un ratito hasta que quede cuadrado. En realidad todo esto está muy bien explicado en el tutorial que enlacé antes, especialmente en un capítulo en el que se da un bucle básico y en otro posterior donde se mejora la implementación. Como digo en el título, hacer un bucle principal es muy sencillo teniendo en cuenta cuatro cosas que son muy conocidas y que este tutorial cuenta muy bien. Pero ojo, ¡es muy importante tenerlas en cuenta!.

Lo que no me gusta tanto del tutorial es el diseño de clases que se da en su implementación, ya que me parece bastante "sucio", haciendo que la clase principal herede directamente de Thread y obligando además al que la use a extender directamente esta misma clase para poder hacer una implementación para un juego concreto. Así que decidí cambiar este diseño y hacer uno más genérico, con una clase limpia GameController que se pueda invocar fácilmente desde el Activity y que use el thread de forma interna. Incorporé las clases Camera y GameMotionEvent que he contado en el punto anterior, para el escalado de los gráficos. Y para permitir la implementación concreta de los objetos creé primero un interface básico GameEntity, con lo mínimo que se necesita para pintar un objeto y que reaccione a eventos. Luego creé otro extendido Scenario, que me pareció interesante para facilitar la creación de "partes" del juego completamente diferenciadas entre sí.

Este es el diseño que quedó:



Continuará...

Y hasta aquí por hoy mis historias programando el juego en Android. Haré un capítulo más, en el que contaré otros refinamientos que he hecho en el diseño, sobre todo para poder tener un sistema sencillo de componentes gráficos y otras cosas como animaciones y efectos. En breve aquí mismito.


West Bank: Crónica RetroMadrid 2013

Antes que nada, os presento al gran campeón del concurso, y ganador de la exclusiva camiseta de West Bank, con una impresionante puntuación de 196,900 puntos... ¡ARQUILLOS!

Arquillos, campeón del concurso West Bank

VTC con la camiseta de Ardent Monkey
También estuvo presente VTC, el segundo clasificado, con una puntuación de 144,910 puntos. VTC por su tenacidad y también gran puntuación, ganó un improvisado segundo premio, una camiseta de Ardent Monkey Games. Como anécdota, comentar que VTC hizo esta gran puntuación sin pasar de la fase 1, ya que no se había dado cuenta de que se podía mover de unas puertas a otras para pasar de fase (error nuestro, en realidad, ya que sólo se explica en la página del Play Store pero no dentro del juego). De hecho, el propio Arquillos nos comentó que para conseguir su máxima puntuación decidió no pasar de fase adrede y se quedó en la segunda, para conseguir ahí el mayor número posible de puntos.
VTC: "¡Así es más divertido!"

La experiencia ha sido muy gratificante, mucha gente pasó por el stand y nos comentaba que le había gustado mucho la conversión y que el juego seguía siendo un vicio a pesar de los años transcurridos. También hemos recibido mensajes del mismo estilo por otros medios, como Twitter, email o el propio Google Play. Incluso gente comentándonos que sus hijos y sobrinos pequeños (¡7 años!) estaban viciándose con el juego. ¿Los clásicos nunca mueren?.


"Foto de familia": los dos primeros clasificados, y Adr y yo haciendo el ganso

Por otra parte, tuvimos un visitante especialmente ilustre en el stand... ¡¡¡Álvaro Mateos, el creador del juego original!!!. Muy majete, y algo sorprendido por todo lo que estábamos montando, me estuvo enseñando la versión que hizo para iPhone (también hay otra para Windows Phone) y que está muy muy bien, con lo cual entre él y nosotros tenemos bastante cubiertos la mayor parte de dispositivos móviles. Añado que una de las preguntas que más nos hizo la gente en el stand fue si íbamos a hacer versión para iPhone. No, no vamos a hacer versión para iPhone, ya está hecha, es esta versión hecha por el propio Álvaro, está disponible en el Apple Store, y el interfaz es muy muy similar a la nuestra (tiene cosas de su propia cosecha, como la carga del juego en cassete). Más información en su web.

Álvaro y yo (y una luz al fondo para que no se vea nada,
¡ya le daré lo suyo al fotógrafo!)

La verdad es que no nos podemos quejar nada de la acogida del juego, en una sola semana desde su presentación lleva ya alrededor de 250 descargas, y ahora mismo la han puntuado en el Play Store 13 personas y todas le han puesto un 5 (la máxima puntuación). El concurso también ha sido un éxito, al principio me cortaba para no hacer puntuaciones demasiado altas y copar yo el top, y ahora ya ni estoy entre los diez primeros... ¡algo que pienso remediar los próximos días, cagontó!


Stand de Ardent Monkey
en RetroMadrid
Por otra parte, muchas publicaciones "retro" se han hecho eco del remake, ¡muchas gracias a todos!:

Tabla de puntuaciones al acabar el
concurso. ¡Impresionante!
Aparte de esto, la RetroMadrid en sí estuvo genial, hacía años que no estaba y me lo pasé realmente bien, muy bien la organización y muy buena calidad en general en el resto de expositores, con mucha presencia de máquinas arcade y "bartop" (a las que miro con deseo aunque al final me contuve y no llegué a comprar ninguna), y muchos imancitos, llaverillos, posters y demás coñas que tanto nos gustan a los retro-frikis. Muy buena la experiencia de compatir expositor con los amigos del CAAD, y genial haber conocido al gran Andrés Samudio (y muy buena su charla, intentando no caer en tópicos).

¿Y ahora?. Nuestro próximo reto es hacer que el juego sea atractivo para las nuevas generaciones, es decir, para la gente que no jugó ni conoció el juego original, ni tampoco le atrae especialmente la estética retro. Creo firmemente que la dinámica del juego es perfectamente válida para el público general, y vamos a intentar demostrarlo.

Para eso, estamos preparando una versión con nuevos gráficos hechos de cero y nuevos sonidos y músicas. Bueno, y con ayudas para que quede clarito cómo moverse entre las puertas, ¡sigh!.

Permaneced atentos al Play Store, cualquier día de estos puede aparecer una actualización del juego con la que podréis sentiros seguros para enseñársela a vuestros amigos, hermanos, padres, abuelos, hijos, sobrinos... y hasta a vuestr@s churris, sin que os miren con cara rara, en plan "que ya tienes una edad... ¡CRECE!".

CONCURSO West Bank RetroMadrid

Saca la mayor puntuación en el remake de West Bank para Android, ¡y gana una estupenda camiseta!.

¡¡¡YA puedes empezar a participar, dale caña!!!

La camiseta se recogerá en la RetroMadrid este mismo Sábado. ¿A qué estás esperando?. ¡No dejes ni uno vivo!




Más información sobre el proyecto y su desarrollo aquí.

Proyecto: West Bank Android

En las últimas entradas, todas muy retro, he ido dejando pistas de que tenía un proyecto en marcha. Pues bien, hoy toca desvelarlo.

Durante estos últimos meses he estado programando... ¡¡¡un remake del WEST BANK para Android!!!.

El juego original

Corría el año 1986. La compañía española pionera por excelencia, Dinamic, estaba empezando a expandirse. Los hermanos Ruiz habían decidido no publicar sólo sus propios juegos, sino promocionar también juegos programados por otras personas. Los tiempos eran muy distintos a los actuales. Triunfaban los ordenadores de 8 bits (que normalmente se usaban como el equivalente a las consolas actuales), como el ZX Spectrum, el Amstrad y el Commodore, pero no existía prácticamente una industria del videojuego en España para ellos. Los juegos los hacía, normalmente, un adolescente en su casa, él solo o con un grupete de amigos.

Los hermanos Ruiz habían demostrado desde el principio una gran habilidad para publicitar sus juegos. Ese mismo año habían tomado la que probablemente fue su decisión más importante: encargar al gran Alfonso Azpiri que les hiciera las portadas. Gracias a esto, estoy seguro de que a mucha gente le sonará la estupenda portada del juego incluso aunque no llegara a jugarlo en su día. [Azpiri sigue en activo y en buena forma, actualmente y junto a Forges está publicando una original y divertida línea de adaptaciones al comic de libros de terror que os recomiendo, Horreibols and terrifics books].

Rocky fue el primer  juego cuya portada hizo Azpiri. Y a su vez, también fue el primer juego que publicó Dinamic hecho por un programador externo: Álvaro Mateos. Pocos meses después, programado por el mismo Álvaro y con portada del mismo Azpiri, aparecía el juego que nos ocupa: West Bank.

Al ser la programación tan artesanal, era bastante habitual que para inspirarse el programador se basara en una máquina recreativa (o directamente la copiara), ya que ellas sí que tenían una poderosa industria, con compañías grandes detrás como Sega y Nintendo. En este caso, el juego es un clon de la recreativa de Sega Bank Panic, aunque debo decir que las sensaciones al jugar uno y otro, dentro de sus parecidos, son bastante distintas. Además, el West Bank incorporaba cosas de su propia cosecha, como los duelos de final de fase.

El juego (tanto la recreativa como el que nos ocupa) era más simple que el mecanismo de un chupete. En resumen, tienes tres puertas que se van abriendo, si el personaje que aparece detrás te apunta con una pistola le disparas, si no lo hace le dejas tranquilico y te dejará una bolsa con dinero. Cuando haya dinero en las 12 puertas del banco, se pasa a la siguiente fase. Es un juego que prácticamente ya estaba anticuado cuando salió en su día, no olvidemos que para entonces ya habían salido virguerías como el Knight Lore, el Great Escape, el Cobra, el Batman o el Three Weeks in Paradise, todos ellos infinitamente superiores técnicamente.

¿Entonces?, ¿cuál es la gracia de esto?. Muy sencillo. A pesar de lo dicho antes, el juego triunfó porque... ¡¡¡es un juego DIVERTIDÍSIMO!!! 

El equipo: Ardent Monkey Games

Ahora damos un salto al presente, o sea, "ventimuchos" años después. Probablemente no conocéis a Muriel (@jdmuriel), pero creedme si os digo que si tuviera tiempo libre para hacer un 1% de las ideas que se le ocurren continuamente... el mundo se acabaría. Normalmente busca ideas para hacernos ricos, que yo siempre le chafo, pero un buen día se le ocurre otra cosa: "¿Sabes qué juego estaría muy bien para móviles?. El West Bank".

No es una idea que vaya a hacer a nadie precisamente rico, pero hay algo que es indudable: es un juego perfecto para interfaz táctil. No tienes que hacer una conversión chunga con una de esas crucetas dentro del juego que tanto se están usando. Cuando quieras disparar a un tipo, le das con el dedo. Simple.

Además, es un gran juego para partidas "a ratos". Para echar una partidilla mientras vas en el metro o esperas al pesado de tu amigo el tardón.

Por otra parte, llevaba ya tiempo con ganas de hacer algo en Android. La programación para móviles, todavía aunque cada vez menos, es lo que siempre me hubiera gustado que existiera cuando era estudiante. No entiendo cómo a día de hoy los aspirantes a informáticos no hacen programas o juegos en Android. Con el tiempo que le dedicaba yo a alguna basurilla de esas que hacía con el BASIC del Spectrum cuando tenía 13 años, podría haber hecho perfectamente juegos en el móvil, y más aún, encima se moverían con suavidad y serían perfectamente jugables. Incluso se puede conseguir algo de dinerillo si te lo curras bien. Ni te digo ya en la universidad. En fin, todo esto ya lo expliqué en mi entrada de presentación del blog, programar ahora es para nenazas.

El caso es que al final, a pesar de mis dudas por eso de que yo tampoco tengo casi tiempo libre, me convenció.

Por último necesitábamos un grafista. Aunque inicialmente usaríamos los gráficos originales del Spectrum, la idea es que también hubiera otros gráficos nuevos. Y además necesitaríamos dibujos o diseños para otro tipo de cosas, como por ejemplo... el propio logo del equipo.

Por suerte convencimos también a mi hermano, el gran Adr, que es un dibujante acojonante. Aquí por ejemplo podéis ver una serie de tiras cómicas que hizo hace tiempo (y que estaría bien que algún día continuara, la verdad): Operación Dragón... bueno, va, os pongo aquí un par de ejemplos, que mola:



Así, el equipo estaba formado. Tras arduas deliberaciones, decidimos llamarnos Ardent Monkey Games.


El remake

Me complace anunciaros que el remake ya está listo y está disponible en el Google Play Store, completamente gratis.




Los gráficos son estos que veis aquí al lado. ¿Ein?, diréis, ¡pero si esos son los de Spectrum!. Pues sí, la versión disponible actualmente es un calco del juego de Spectrum, con sus mismos gráficos y sonidos.

Las diferencias son: el interfaz táctil, que la puedes jugar directamente con el móvil, y que tiene una tabla de puntuaciones global en un servidor, que comparten todos los jugadores, y con la cual los piques están asegurados. Ya sé que esto hace que el juego sea sobre todo apto para el mundillo retro, pero en poco tiempo saldrá otra versión en la que permitiremos seleccionar el "skin" original o la versión con los nuevos gráficos y sonidos, con lo que el juego será más atractivo para el gran público que no ha visto un Spectrum en su vida.

En resumen, las similitudes con el caso del West Bank original son muchas... es una copia descarada de un juego anterior... lo han hecho unos chalaos en su casa (aunque ya no demasiado adolescentes [ejem])... y lo más importante de todo... ¡¡¡sigue siendo DIVERTÍDISIMO!!!


P.D.: En pocos días os cuento más, que tenemos una sorpresita preparada para la RetroMadrid de la semana que viene...

P.D. 2: Desde aquí, me gustaría también agradecer su amabilidad a Álvaro Mateos, ya que le comentamos nuestra idea de hacer un remake y nos dio sus bendiciones. ¡Álvaro, eres grande!