Nos presentamos al Ho Play

Pues que nos presentamos al Ho-Play, premios vascos al videojuego.

Esta mañana in extremis del plazo, hemos conseguido tener una versión completa del juego para enviarla a ver si suena la flauta en alguna categoría. No tenemos grandes ambiciones porque es un juego muy sencillo y hay mucho nivel, el certamen es internacional, pero quizá podamos aspirar a quedar finalistas en alguna categoría menor y seria un subidón.

El juego lo damos ya por terminado y estamos preparando las dos versiones , gratuita y de pago, para publicarla.

Para celebrarlo, pongo por error una captura secreta de la fase extra

Image

Nuevo vídeo con mejoras

Hola, hete aqui un nuevo vídeo con las sombras dinámicas, mejoras en los niveles y, por fin, la terrorificachonda  música que se ha currado John Morin en exclusiva para este juego. Ya han empezado a circular copias del juego entre algunos betatesters selectos y estamos puliendo detalles y afinando. Si el crowdfunding sale, podremos dedicarle algo más de tiempo e incorporar un paquete de niveles extra a los que ya hay, en caso contrario, sera muy triste todo y tendremos que publicarlo como está y empezar un juego nuevo para animarnos.

La están peinando…

Estamos en la fase final del juego. Todo el codigo funciona perfectamente ya, la lista de bugs esta clara y contenida, y es tiempo de retocar y mejorar cosas y hacerlo más gracioso. Estamos repasando todos los niveles retocandolos estética y funcionalmente para hacer una curva de dificultad lógica y equilibrada. Las 3 áreas por donde transcurre el juego tienen diferencias de comportamiento:

• El templo: La bola cae solo por los agujeros, normalmente se puede apoyar en paredes y demás
• Las minas: La bola se cae fuera del camino, pero hay un carril que ayuda a mantenerla en su sitio.
• La selva: La bola se cae fuera del camino, y no hay ninguna ayuda para mantenerla.

A partir de estas 3 clases, estamos haciendo unos niveles base y algunos que son combinaciones de los básicos en función de de trampas y efectos.
Y estamos metiendo los toques extra que diferencia a un juego de otro, los detalles y las chorradas.Por ejemplo, la antigua y fea pantalla de las plataformas, ahora contiene el majestuoso trono de Mah-Trakka, con el emblema de la Mosca Aúrea, animal sagrado, grabado en el respaldo.

Image

El botón para cambiar la vista de cámara ya tiene su iconito y todo. La salida  del templo tambien ha sufrido cambios. El inane escenario antiguo ha sido decorado con reproducciones del Demonio Goh-Ron y carteles para facilitar su visita, ademas de mejoras en la resolución de las texturas y railes. Pongo el antiguo y el nuevo. No vamos a poner muchos más para no chafar todas las sorpresas, paladeadlos.
cueva

capturanueva1

 

[edito] Añadimos un pantallazo de la nueva selva, para que haya un representante de cada nivel (templo, minas y selva):
capturanueva3

Algunas nociones sencillas de matemáticas en programación.

Las viejas matemáticas simplonas, los problemas que nos dieron en la EGB (a los que ahora somos viejos y caducos) y los problemas que nos resuelven ahora. Por ejemplo, los botones para conmutar estados. Nos gusta reducir al mínimo los condicionales (if … then…) para reducir el código y hacerlo mas legible. Pongamos que tenemos un botón que active o desactive cierto estado, podemos hacerlo así, suponiendo que el estado pueda ser 1 o 0  (pongo código «inventado» para facilitar la comprensión, la sintaxis de javascript en unity es muy distinta)
if pulsarboton {
if (estado=1) then (estado=0) else (estado=1)
}

Pero recordemos que según las matemáticas esas, positivo * positivo=positivo, positivo*negativo= negativo y negativo * negativo= positivo, así que podemos simplificar el código si dejamos los posibles estados como 1 y -1 en vez de cero, y al pulsar el botón se multiplica por -1, quedaría de esta manera:
if pulsarboton {
estado= estado *-1
}

Y se conmuta el estado automáticamente de forma un poco más sencilla y sin bucles «if». Otro truco para evitar condicionales es usando la propiedad de que  cualquier numero multiplicado por cero es igual a cero. Pongamos que tenemos una variable x que se incremente o decremente al pulsar los botones de izquierda-derecha para menear un personaje, podemos hacerlo así.
if pulsarizq=1 {
x=x-5
}
if pulsarder=1{
x=x+5
}

Pero podemos simplificarlo así en una sola linea sin «ifs»:
x=x+(5*pulsarder)-(5*pulsarizq)

Si uno de los dos valores es 1 se realizara la suma/resta, sino, sumara cero y no se moverá. Si queremos añadir inercia para hacer el movimiento más natural, o simular que el personaje anda sobre el hielo, no variaremos directamente la posición x del personaje, sino que cambiaremos su aceleración con una variable intermedia.
acel=acel+(5*pulsarder)-(5*pulsarizq)
x=x+acel

Si queremos que el personaje frene si no se pulsan los botones, hay que hacer que ac tienda a cero añadiendo algo como lo siguiente:
acel=acel/2

Y ademas hacer que la aceleración se convierta en cero si es muy pequeña
if (acel*acel)<0.4 {
acel=0
}

Usamos el cuadrado de ac para convertir su valor en positivo y evitar dos condicionales, uno si es positivo y otro si es negativo. Con el truco anterior, aun podemos eliminar el if y juntar todo lo anterior haciendo esto:
acel=(acel/2)*((acel*acel)>0.4)+(5*pulsarder)-(5*pulsarizq)

De esta forma, si acel al cuadrado es menor que 0.4, la comparación devuelve cero (false) que al multiplicar por la aceleración anula esta, y hemos incluido también el control y el frenado sin tener que utilizar ni un solo bucle if y en una sola linea. Nuestro programador es un crack. Espero que no se entere la competencia y le llame.
Cambiando los distintos valores, haremos que el personaje acelere o frene mas rápido, pudiendo simular que camina sobre tierra, hielo, manchas de aceite, etc.

Otro caso que nos ha ocurrido recientemente, aunque en otra aplicación, no en este juego, demuestra que mucha veces es mejor gastar el tiempo buscando el camino más sencillo que torturando una solución complicada para que funcione. Es un juego en el que podemos colocar en cualquier posición una muñeca articulada en 2d, una especie de marioneta. Queríamos que al mover la mano, la combinación brazo-antebrazo se moviera de forma natural siguiéndola, lo que se conoce como  cinemática inversa (IK) en animación. Estuvimos probando pluguins y código ajeno, pero eran muy complicados porque estaban preparados para múltiples articulaciones en un escenario 3D, nos rompimos la cabeza intentado simplificar el código para limitar la rotación solo en un eje sin mucho éxito, hasta que nos dimos cuenta que en realidad, estábamos hablando de resolver los ángulos de un triangulo conocidos la longitud de los tres lados (el brazo, el antebrazo y la distancia entre la mano y el hombro), que como todo el mundo sabe (después de buscar en internet)  sigue la siguiente formula:

triangulosAsí (usando la inversa del coseno) sabemos en que angulo tenemos que girar los objetos que forman el brazo y el antebrazo. Con un par de ajustes funciona perfecta y rápidamente  sin usar complicados algoritmos.

Bueno, igual todo esto le sirve a alguien, se puede aplicar a cualquier lenguaje de programación con los debidos retoques, seguimos en contacto, adeu.

Algunos trucos sucios

Vamos a contaros ahora algunos de los sucios trucos que hemos usado con el noble fin de trabajar menos o sortear problemas que nos costaría mucho resolver de forma mas «limpia».
Como comentaba en otro post el explorador tiene velocidad variable, corre más cuando la roca esta cerca. Esto tiene dos objetivos:

-Por una parte, hacerlo más divertido y «realista»
-Por otra, dar más margen y libertad de juego. Supongamos que el explorador tardase de forma fija 30 segundos en recorrer el laberinto, entonces solo tendríamos ese tiempo para resolverlo antes de aparecer el mensaje de fin de partida, y resultaría frustrante, no tendríamos tiempo para acostumbrarnos, sobre todo en fases complicadas y tendria un comportamiento muy rígido.

Hemos hecho que el mangante deje de acelerarse al tener la roca cerca cuando se encuentre a cierta distancia de la salida. Antes de que llegue a ese punto, correrá tanto que será imposible cazarlo.
Así, un jugador experimentado puede acabar la pantalla en los 30 segundos mencionados antes, con el explorador corriendo a toda leche, pero un jugador novato podrá acabarla en (pongamos) un minuto atascándose por el camino, con el explorador corriendo despacio. En la practica funciona como un temporizador con un máximo y un mínimo. Por eso el consejo para pasar las pantallas es sobre todo centrarse en resolver el laberinto sin intentar chafar al tipo antes de tiempo.

Programar es como descabezar una Hidra, cuando  resuelves un problema aparecen 3 nuevos. Por ejemplo, en la fase del molino, el tema de sincronizar el giro de las aspas con la vagoneta para evitar que se golpeen seria facil si la velocidad fuera fija, pero no sabemos cuando va a llegar el personaje a las aspas para ajustar su giro. La forma más sencilla que hemos encontrado es algo parecido al truco de la visión de aquel post, poniendo unos objetos invisibles pegados a las aspas.  En la siguiente imagen los hemos hecho activado para que se vean, los que están pintados en blanco, hacen que el molino acelere al colisionar con la vagoneta, los amarillos, que frene. Así evitamos que choque con ella. Es un truco sucio pero no se nos ha ocurrido otra forma de hacerlo.
detectores

La siguiente jugarreta avergüenza al diseñador pero tendrá que vivir con ello. Durante las fases de las minas, el explorador pasa de ir corriendo a montar en una vagoneta. Le pedimos que hiciera una animación de forma que saltara dentro y se pusiera en marcha y ¿que nos entrego? El personaje se mete en una cueva y vuelve a aparecer ya montado y se ahorró todo el curro de animarlo. Se aprovecha de que no puedo rebajarle el sueldo (no tiene)
cueva

El siguiente truco es sensato y se usa mucho en juegos, utilizar colisionadores sencillos ocultos bajo formas complejas que en realidad no afectan. En nuestro caso, a veces aparecen unos esqueletos de antiguos saqueadores sin fortuna que entorpecen la marcha de la roca. Los huesos en realidad no afectan a la bola, sino unas pirámides que hay ocultas en su misma posición. Esto hace que las físicas sean mas rápidas porque al procesador le cuesta menos calcular las colisiones de la bola con objetos sencillos (como las pirámides) que con objetos complicados como los huesos con sus recovecos y esquinas. En la siguiente foto hemos apagado el esqueleto de la derecha e  iluminado las pirámides para que las veáis. En los juegos, como en la tele, todo es mentira.

esqel

Ale, ya os contaremos más problemas que nos hemos encontrado, por desgracia hay material para muchos posts, hasta luego.

Manejando el caos pantallistico

Cuando hacíamos (y hacemos) webs nos quejábamos (y nos quejamos) mucho del problema de las diversas resoluciones de pantalla. Una web se tiene que ver correctamente tanto en monitores con un ancho de 800px como de 1200px, por lo menos.
Bien, para que os hagáis una idea de como están las cosas en el mundo de las apps, en el siguiente gráfico están todas las resoluciones posibles de los dispositivos Android e iOS.
pantallas-800x400
Una locura no, mucho peor. Gracias a nuestra experiencia en webs «liquidas» (adaptables a diversos anchos), conocemos varias estrategias para superar algo este problema que podemos adaptar al diseño de videojuegos.

Lo primero es no utilizar posiciones absolutas sino relativas, es decir, en vez de posicionar los botones en coordenadas fijas x e y, lo hacemos tomando como referencia los bordes, es decir, a x distancia de la izquierda, a x distancia de arriba, etc.
La segunda es tomar como referencia un porcentaje del ancho y trabajar en base a el. En nuestro caso, lo llamamos modulo, añadimos otro modulo vertical para ciertos posicionamientos (modulov=Screen.height/10).
Todos los elementos de la interfaz están basados en dimensiones divisibles entre si en números enteros, por ejemplo tal boton es 4x de ancho por 1x de alto, tal fondo es 4x por 3x, tal rotulo mide 8x por 1x. Normalmente, las dimensiones son en numero de pixels de base 8 porque el procesador trabaja mejor con ellas, lease 16, 32, 64, etc.

Nada mas arrancar el juego definimos que «modulo» es igual, por ejemplo, al ancho de la pantalla dividido entre 20. Así, sabemos que la mitad horizontal de la pantalla esta en 10 x modulo, y el botón anteriormente citado medirá 4 x modulo de ancho y 1 x modulo de alto,  el fondo medirá 4 x modulo y 3 x modulo, etc.  El tamaño de las fuentes también lo ajustamos tomando como referencia dicho modulo. Asi se conservan las proporciones sin deformarse y se adaptan a cualquier dispositivo. El tamaño vertical también puede variar, pero siempre está seguro entre las proporciones 4:3 (no hay pantallas cuadradas) y 16:9 de los móviles y tabletas panorámicos, entonces simplemente nos aseguramos de dejar suficiente «aire» a los lados para que no se corten los elementos, algo de lo que tenemos también experiencia por nuestros trabajos en vídeo, donde se reproducía el problema de que un videoclip o cortometraje se pudiera ver bien tanto en teles «cuadradas» como panorámicas, esto se llama «área segura» (o «safe area» en inglis) y todos los elementos importantes se tenían que poner dentro de ese área.
En la siguientes capturas podéis ver como se adaptan los botones con dos proporciones «extremas» en el juego de Mah-Trakka siguiendo estas reglas, posiciones y tamaños relativos y «aire» a los lados.
capturasresol

Se puede ver que lo importante, el rotulo superior y el personaje corriendo, se ven bien. Luego ya es cuestión de probar en distintos dispositivos y retocar lo necesario, por ejemplo, en estas capturas falta definir dos anchos de boton, para textos largos o cortos.
Como siempre, recordamos que somos inexpertos y muy posiblemente existan estrategias o trucos mejores, si alguien los conoce, que los apunte en los comentarios 😉

Programando el miedo

El movimiento del personaje se basa en una serie de puntos (waypoints) sobre el escenario que va recorriendo por orden. Al principio los recorría sin más, un punto tras otro. Para evitar el problema de que la bola lo adelantara y se dirigiera hacia ella (lo que no dejaría en buen lugar su inteligencia) habíamos pensado en hacer los escenarios de forma que el recorrido fuera lineal, sin la posibilidad de que la bola pudiera adelantarle sin chafarlo.

Luego decidimos que si veía la roca delante pudiera girarse para esquivarla. Eso evitaría que se comportara como un robot, y así también podíamos hacer escenarios más abiertos y añadía jugabilidad y diversión al hacer al ladrón capaz de esquivar la bola en cierta medida. ¿como hacer que ind… perdón, el mangante viera la roca? Lo primero que pensamos fue en complicados algoritmos basados en la distancia, orientación, etc. pero al diseñador se le ocurrió una solución mucho más sencilla. Creamos un objeto triangular y lo pegamos al personaje haciendo que detectara la colisión con la bola. Este objeto seria invisible y ademas de permitir una programación muy sencilla podíamos cambiar su ancho y largo fácilmente para hacer que el personaje viera mas lejos o mas «ámplio». Si el campo de visión chocaba con la bola, sencillamente decíamos que el próximo waypoint fuera el anterior en vez de el siguiente en su lista. Añadimos un punto extra al que solo se dirigiría si hubiera llegado al primero para evitar un movimiento de ping pong si no quedaban waypoints anteriores. Se puede ver claramente en el siguiente vídeo, donde hemos iluminado el objeto campo de visión en verde.
Ademas, también se aprecia bien otro comportamiento añadido para que sea mas gracioso y dinámico, corre más cuando la roca esta cerca, ampliaremos la información sobre esto en otro post.