jueves, 19 de enero de 2017

Animaciones

Los juegos no son juegos si no se siente vida en ellos. ¿O acaso a alguien le gustaría jugar con el Word? Una parte fundamental para dar vida a los juegos son las animaciones. Las animaciones nos hacen ver que el mundo del juego no es estático.

Un Spritesheet específico

En los juegos 2D normalmente animamos los sprites cambiándolos completamente con otro sprite similar. Normalmente todas las imágenes que van a representar un sprite se almacenan en el mismo archivo. Recuerda la lección sobre Spritehsheets.

Para este ejemplo voy a usar este spritesheet.
Es obra de Brett Steele. He hecho una modificación para que el color azul se vuelva transparente.

Generando animaciones

En primer lugar cargamos el spritesheet.


    function preload() {
        game.load.spritesheet("mujer", "mujer-alpha.png", 32, 64);
    }

Después añadimos las animaciones al sprite. El primer argumento es el nombre de la animación, el segundo es la lista de frames de los que se compone la animación. Estos son los frames del spritesheet. Por último la velocidad de la animación y si queremos que se repita.

function create() {
        cursor = game.input.keyboard.createCursorKeys();
        mujer = game.add.sprite(100, 100, "mujer");
        mujer.frame = 10;

        mujer.animations.add("left", [24, 25, 26, 27, 28, 29, 30, 31], 10, true);
        mujer.animations.add("right", [16, 17, 18, 19, 20, 21, 22, 23], 10, true);
        mujer.animations.add("up", [0, 1, 2, 3, 4], 10, true);
        mujer.animations.add("down", [8, 9, 10, 11, 12], 10, true);
    }

Después lo podemos usar en la función update donde arrancamos y paramos las animaciones según la entrada de teclado.


    function update() {
        if (cursor.left.isDown) {
            mujer.animations.play("left");
            mujer.x--;
        } else if (cursor.right.isDown) {
            mujer.animations.play("right");
            mujer.x++;
        } else if (cursor.up.isDown) {
            mujer.animations.play("up");
            mujer.y--;
        } else if (cursor.down.isDown) {
            mujer.animations.play("down");
            mujer.y++;
        } else {
            mujer.animations.stop();
            mujer.frame = 10;
        }
    }
Con <sprite>.frame podemos ajustar manualmente el frame de la animación, muy útil cuando hemos parado la animación.

Resultado

Ahora podemos ver el resultado.

viernes, 13 de enero de 2017

Diferencia entre Arcade, Ninja y P2 physics en Phaser

Mucha gente tiene dudas de por qué hay tres motores de física en Phaser. Y sin contar Box2D que es un plugin de pago para Phaser. ¿Cuáles son las diferencias entre estos tres motores?


Arcade Physics

Arcade Physics únicamente detecta colisiones de tipo AABB. Es decir, se generan rectángulos y se comprueba si se superponen entre sí. En ese caso se entiende que se ha producido una colisión. Es un sistema muy rápido pero no es muy preciso (no todos los sprites son rectángulos perfectos). Es el único motor que además cuenta soporte en la API de Partículas de Phaser.

Ninja Physics

Ninja Physics es más preciso que Arcade. Es capaz de manejar formas complejas y rotaciones. Se recomienda para el diseño de niveles, por ejemplo, de un plataformas.

P2 Physics

P2 es un motor físico completo, con más cosas aparte de colisiones complejas como fuerzas y aceleraciones. Es el más lento de los tres pero es el más completo. Se recomienda cuando tenemos objetos a los que queremos dotar de física completa, por ejemplo, los pájaros de Angry Birds.

sábado, 7 de enero de 2017

Este 2017, OneGameAMonth

¡Feliz año nuevo a todos nuestros lectores! En estas fechas la gente suele ponerse propósitos. Cosas que intentarán cumplir durante el nuevo año y así mejorar como persona. Dejar de fumar, hacer ejercicio, aprender inglés,... Si me preguntáis a mí os diré que no suelo ponerme propósitos y que es mejor aplicar kaizen diariamente. Sin embargo hay un propósito que me hace mucha ilusión y que voy a intentar realizar. Os animo también a vosotros a que los sigáis. Se trata del desafío OneGameAMonth.

Se trata de un desafío con vosotros mismos (o de vuestro equipo). Se trata de hacer todos los meses un juego. No hay más normas. Es un reto personal, de disciplina, de mejora continua. Podéis usar cualquier tecnología. La comunidad #1GAM que se encuentra por las redes sociales os ayudará a mantener la motivación y a compartir los progresos que vayas realizando. El objetivo no es hacer un The Witcher 3 cada mes, sino un pequeño juego, a poder ser con una idea innovadora. Quizá el año que viene uno de los 12 juegos que hiciste te gustó más que el resto. Con ese juego podrás centrarte el año que viene.

Si tienes Twitter puedes registrarte en la web e ir anotando tu progreso a la vez que ganando puntos de experiencia. No es mal sistema, pero recuerda que lo importante eres tú y no esa web, puedes seguir también el desafío sin estar registrado.

Todos los meses se sugiere un tema y eres libre de seguirlo o no. Personalmente en competiciones de menos horas el tema me parece más importante que en este desafío personal que es #1GAM y en mi caso no lo voy a seguir.

Anímate y comenta tu progreso en #1GAM en el foro de Gamedev Hispano.

jueves, 5 de enero de 2017

Partículas en Phaser

En esta entrada vamos a ver como usar partículas en Phaser. Para ilustrarlo intentaremos construir un fluido.

El concepto de partícula

Para construir nuestro fluido vamos a usar partículas. ¿Qué son las partículas? Podemos entenderlo como pelotillas o puntos, cada una independiente del resto de las demás partículas pero que se usan de forma combinada para generar formas. Las partículas se pueden usar para generar fuegos artificiales, fluidos, humo, lluvia, etc

En el caso del agua es fácil de entender. Podemos asimilarlo a la realidad donde el agua contenida en una copa está formada por moléculas de H2O.

El sistema de partículas en Phaser

Phaser cuenta con un sistema de partículas, que usa Arcade Physics como motor de física. Es interesante usar un sistema de partículas siempre que sea posible pues normalmente ya están optimizados para trabajar con grandes cantidades de objetos. Usando Arcade Physics tendremos varios problemas y no es 100% válido para fluidos (si lo es, por ejemplo, para explosiones y fuegos artificiales). En otro post veremos como diseñar fluidos de forma más completa usando otro motor de físicas.

En el sistema de partículas de Phaser hay dos clases importantes: Emitter y Particle. Estas dos clases son las que usaremos. La clase Particle derive de Sprite por lo que todo lo que podías hacer con un sprite lo puedes hacer con un Particle. Por su parte Emitter es el emisor de partículas. Tiene una posición en la pantalla y es invisible pero de él salen todas las partículas.

Simples pelotas

Vamos a hacer un programa que suelte pelotas naranjas. El código es el siguiente:

var game = new Phaser.Game(800,600,Phaser.CANVAS,"particulas",{preload: preload, create: create, update: update});

var emitter;

function preload(){
    game.load.spritesheet("pelota","pelota.png",16,16);
}

function create(){
    emitter = game.add.emitter(64,64,400);
    emitter.makeParticles("pelota",0,400,true,true);
    emitter.setXSpeed(-64,64);
    emitter.setYSpeed(-10,10);
    emitter.gravity = 1000;
    emitter.bounce.setTo(1,0.7);

    emitter.start(false,0,10);
}
function update(){
    game.physics.arcade.collide(emitter);
}


Veamos el código. En la función create añadimos un Emitter en la posición 64,64. Indicamos que emitirá como máximo 400 elementos. Posteriormente pasamos a crear las partículas, usamos la imagen pelota, generamos 400 y activamos las colisiones tanto con otras partículas como con los bordes de la pantalla.

A continuación unos ajustes con los que podemos jugar hasta que demos con los que nos gusten. La velocidad en X y en Y se refiere a la velocidad mínima y máxima que pueden tener las partículas al salir. Phaser aleatoriamente les dará velocidades dentro del rango. La gravedad que afecta a las partículas y por último el rebote, indicando un rebote para el eje X y otro para el eje Y. Un rebote de 1 quiere decir que no pierde velocidad al chocar con otra partícula en ese eje.

Finalmente podemos arrancar con start. El primer argumento sirve para indicar si va a ser una explosión (todas las partículas de golpe) o no. El segundo argumento indica cuanto tiempo van a mantenerse en pantalla las partículas, un valor de 0 hace que duren para siempre. Por último, indicamos en milisegundos cada cuanto queremos que salga una partícula nueva.

En la función update llamamos a Arcade Physics para que compruebe las colisiones de las partículas y las separe.

Si ahora pruebas a aumentar el número de partículas mientras las sigues haciendo más pequeñas conseguirás un fluido cada vez más realista.