sábado, 30 de julio de 2016

Entrada táctil, ratón y teclado

En este tutorial vamos a ver como manejar la entrada del usuario en nuestro juego con Phaser. Hoy en día existen muchos dispositivos diferentes, cada uno con sus peculiaridades. Donde hace unas décadas solo era teclado ahora tenemos ratón, pantallas táctiles y joysticks. Phaser intenta gestionar todas las diferencias de control simplificando conceptos, así, aunque es posible controlar el ratón y la entrada táctil por métodos distintos, Phaser recomienda simplificar y denominarlos punteros con botones, de los cuáles siempre puede haber varios (para gestionar el multitouch) y que no sabremos si son ratones o dedos. Adicionalmente el teclado puede seguir usándose, pero deberás saber que en móviles y tablets los usuarios no tienen acceso a teclado. También con los joysticks o gamepads, Phaser trae funciones para gestionarlos pero no todos los usuarios de tu juego tienen porque tener esos dispositivos. El control que uses será en definitiva una decisión tuya.

Teclado

Vamos a empezar por el teclado. Hay varias maneras de detectar una tecla. Principalmente hay 3 sistemas:
  • Ha sido pulsada (genera un evento)
  • Comprobamos si actualmente esta pulsada
  • Ha sido liberada (genera un evento)
Las opciones que generan eventos son mejores en juegos, donde no se requiera mantener pulsadas las teclas. La mayoría de juegos, sin embargo, irán mejor con el sistema de enmedio.

Muchos juegos usan las teclas en forma de flecha para el control. Phaser trae la función createCursorKeys para facilitarle la vida a los desarrolladores de esos juegos.


var cursor = game.input.keyboard.createCursosKeys();
Luego, en la función update del juego podemos comprobar si alguna tecla esta pulsada y actuamos en consecuencia. Por ejemplo, en un juego con un personaje, mantener pulsada la tecla será seguir dándole velocidad al personaje para que siga avanzando.

function update(){
    if(cursor.up.isDown){
        // La tecla de flecha hacia arriba está pulsada, actuaríamos en consecuencia
    }
    if(cursor.left.isDown){
        // La tecla de flecha hacia la izquierda está pulsada
    }
}
Si quieres añadir más teclas que funcionen manteniendo pulsado puedes usar la función isDown proveyendola del identificador de tecla o keycode.

function update(){
    if(game.input.keyboard.isDown(Phaser.KeyCode.SPACEBAR)){
        /// La barra espaciadora está pulsada
    }
}

En ocasiones que el usuario pulse una tecla puede interferir con el funcionamiento del navegador. Podemos bloquear este comportamiento con addKeyCapture. Se encargará de que las teclas pulsadas no se transmitan más que a Phaser.

addKeyCapture(Phaser.KeyCode.SPACEBAR);

Si deseas que las teclas no sean de mantener, sino que propaguen acciones inmediatamente (por ejemplo, cambiar de radio en el GTA, solo es un toque, mantenerlo pulsado no hace nada más) podemos sobreescribir onUpCallback. Una vez se haya disparado el evento comprobaremos que tecla es la que ha sido pulsada.


game.input.keyboard.onUpCallback = function(key){
    if(key.keyCode === Phaser.KeyCode.G){
       // La tecla G acaba de ser pulsada y soltada. Si se mantuviese la tecla pulsada no pasaría nada.
    }
}

Punteros (ratón y táctil)

Phaser unifica el ratón y los gestos táctiles en los llamados punteros. Para acceder al puntero por defecto podemos usar la propiedad activePointer. Al igual que con el teclado soporta mantener pulsado y un simple toque.

// Mantener pulsado, dentro de la función update
if(game.input.activePointer.isDown){
    if(game.input.x > 500){ // Se comprueban las coordenadas del click
        // Esta tocando o haciendo click en el borde derecho de la pantalla
    }
}

// Pulsar una sola vez
game.input.onUp.add(function(){
    // Se ha presionado y levantado el dedo o el botón del ratón
});


jueves, 28 de julio de 2016

Rectángulos, círculos y formas geométricas

En este tutorial vamos a aprender cómo dibujar figuras geométricas simples, usando el módulo Phaser.Graphics. Las funciones son parecidas a las de la API Canvas 2D de HTML5 pero mejoradas y con una gran ventaja, funcionan tanto en el renderizado via WebGL como en el de Canvas 2D. Las funciones pueden ser llamadas desde cualquier parte del código, pero es recomendable situar las operaciones de dibujado de escenario en la función create.

Creando un objeto gráfico o lienzo

Antes de dibujar tenemos que crear un lienzo u objeto gráfico. Podemos tener tantos lienzos como queramos. Cuando creemos el lienzos indicaremos la posición de la esquina superior izquierda del lienzo en la pantalla del juego. Es decir, el punto desde el cual el lienzo crece horizontalmente a la derecha y verticalmente hacia abajo, según nuestras necesidades.


var lienzo = game.add.graphics(0,0);

En este caso el lienzo puede ocupar toda la pantalla, pues empieza en las mismas coordenadas que la pantalla del juego. Para aclararte con las coordenadas en Phaser he aquí un gráfico.

Colores

Lo primero que hay que hacer al trabajar con Phaser.Graphics es asignar el estilo de dibujado, es decir, los colores que tendrán diversas partes de la figura. Existen dos funciones para trabajar con ellas: beginFill y lineStyle. beginFill se refiere al color del relleno y lineStyle se refiere a los bordes.

El procedimiento de dibujado es muy sencillo. Todas las operaciones con relleno han de comenzar con beginFill y acabar con endFill. Entre medias, todas las figuras geométricas que dibujemos tendrán los colores especificados por beginFill. Si dibujamos una figura sin relleno solo veremos el borde, según lo especificado en lineStyle. Así, si tenemos beginFill/endFill tendremos un círculo, mientras que si usamos lineStyle solamente, dibujaremos la circunferencia correspondiente de ese círculo. 


function create(){
    var lienzo = game.add.graphics(0,0);
    lienzo.beginFill(0xfa33aa);
    // dibujar las figuras ... lienzo.drawRect, lienzo...
    lienzo.lineStyle(20,0xff5500,1);
    // dibujar figuras con borde
    lienzo.endFill();
}

El color ha de especificarse en formato hexadecimal. 


Rectángulos y círculos

Los rectángulos se dibujan con drawRect. Indicamos las coordenadas de la esquina superior izquierda y de el ancho y alto del rectángulo.

lienzo.beginFill(0xfa33aa);
lienzo.drawRect(10,10,200,50); // coordenada X, coordenada Y, ancho y alto
lienzo.endFill();

Este código, en la función create nos dará el siguiente resultado.
Podemos especificar rectángulos con bordes redondeados. Muy útiles cuando creemos interfaces de usuario. Usaremos drawRoundedRect e indicamos el radio de lo bordes.

lienzo.drawRoundedRect(10,10,200,50,10); // coordenada X, coordenada Y, ancho, alto y radio


Para dibujar círculos usaremos drawCircle, indicando las coordenadas X e Y junto con el diámetro del círculo.

lienzo.drawCircle(50,50,50); // coordenada X, coordenada Y, diámetro del círculo


Si usamos lineStyle para el borde

lienzo.lineStyle(10,0xFF00FF,1);
lienzo.drawCircle(50,50,50);

Líneas

Las líneas se dibujan con moveTo y lineTo. moveTo nos permite mover un puntero imaginario por el espacio 2D, especificando las coordenadas. Cuando llamamos a lineTo se dibuja una línea entre la posición actual del puntero y unas nuevas coordenadas. El puntero se desplaza a esas nuevas coordenadas.

lienzo.moveTo(50,50);
lienzo.lineTo(100,100);

Polígonos complejos

Los polígonos complejos, que no son rectángulos, pueden ser dibujados si especificamos una lista de sus vértices con drawPolygon. Los vértices deben ser objetos Phaser.Point.


lienzo.drawPolygon([new Phaser.Point(100,100),new Phaser.Point(200,100),new Phaser.Point(200,200)]);


Arcos y curvas de Bézier

Para figuras más complejas, Phaser soporta arcos y curvas de Bézier. Los arcos son trozos que corresponden a partes del círculo. Usando la función arc se debe indicar el centro del círculo, el radio del círculo y los ángulos de inicio y de finalización. Además hay más ajustes opcionales. Los ángulos se expresan en radianes.

lienzo.arc(50,50,50,0,Math.PI/2); // coordenada X, coordenada Y, radio del círculo, ángulo de inicio, ángulo de finalización (radianes)

Las curvas de Bézier son un método de representar curvas complejas de forma precisa. Phaser soporta las curvas cúbicas de Bézier, es decir: punto de inicio, punto de destino y dos puntos de control.
En Phaser el punto de inicio se especifica con moveTo y el resto de puntos con bezierCurveTo, sin embargo


lienzo.lineStyle(10,0xffffff,1);
lienzo.moveTo(100,100);
lienzo.bezierCurveTo(150,150,300,0,300,400);

Con esto ya tienes más que suficiente para dibujar en Phaser sin necesidad de recurrir a imágenes.

martes, 26 de julio de 2016

Iniciar Phaser.js y pantalla de carga

Una vez ya tengamos instalado Phaser.js y tengamos la estructura de carpetas podemos empezar a escribir en el fichero main.js. Puedes usar cualquier editor de texto. Los mejores son Sublime Text, Atom y Visual Studio (tanto Community, solo Windows, como Code, multiplataforma). También es bueno y rápido Notepad++.

Para iniciar Phaser tenemos que crear un nuevo objeto Game. En Phaser todos los objetos y componentes se encuentran bajo el prefijo Phaser, para que no choquen con otras librerías o nuestros propios componentes. Además Phaser necesita 3 funciones importantísimas, preload, create y update.

  • preload, se ejecuta nada más Phaser es iniciado. La usaremos para cargar los recursos del juego. Haremos una pantalla de carga
  • create, se ejecuta cuando Phaser ha terminado de cargar todo lo necesario. La usaremos para crear los escenarios y personajes.
  • update, se ejecuta constantemente. La usaremos para la lógica del juego (¿has pulsado esta tecla?, ¿el malo te ha dado?,...) pues comprueba constantemente el universo ficticio que creamos en Phaser.



var game = new Phaser.Game(600,480,Phaser.AUTO,{preload: preload, create: create, update: update});
function preload(){

}

function create(){

}
function update(){

}
¿Qué parámetros necesita Phaser.Game?
  • Los dos primeros números son las dimensiones del juego. En este caso, 600 de ancho por 480 de alto.
  • El tercer argumento, Phaser.AUTO, indica a Phaser que motor de renderizado ha de usar. Phaser está basado en Pixi.js y este soporta 2D de dos formas. A través de OpenGL, usando WebGL (modo por defecto, pues usa la tarjeta gráfica y teóricamente es más rápido) y con la API Canvas 2D de HTML5. Esta es soportada por muchos más navegadores, teléfonos, etc. Indicando AUTO le decimos que intente usar WebGL, y si no está disponible, use la API Canvas 2D.
  • El cuarto argumento tiene las funciones básicas de Phaser. En este caso las hemos llamado iguales que como las llama la API de Phaser. Abajo las hemos declarado, pero están vacías.

Una pantalla de carga

La función preload como hemos dicho sirve para cargar todo lo que necesitemos en el juego. Phaser gestiona las cargas de una manera muy sencilla, a través de un objeto Phaser.Loader accesible en game.load. Lo primero que tenemos que hacer es añadir una lista de recursos que deben ser cargados.

function preload(){
    game.load.image("imagen","img/imagen.png"); // Cargar una imagen, con ID imagen, ubicada en img/imagen.png
    game.load.images(["chico","chica","policia"],["img/chico.png","img/chica.png","img/policia.png"]); // Añade imágenes en lote
    game.load.audio("disparo","sfx/disparo.ogg"); // Carga un audio en formato Ogg
    game.load.audio("disparo",["sfx/disparo.ogg","sfx/disparo.wav"]); // Carga un audio y elije el formato que más convenga según el navegador
    game.load.pack("nivel1","maps/nivel1.json"); // Carga los recursos especificados en el fichero PACK
    game.load.tilemap("casa","maps/casa.json",Phaser.Tilemap.TILED_JSON); // Carga un mapa de Tiled en formato JSON 
}
Con estas funciones tendrás suficiente para ir cargando tus recursos, pero Phaser dispone de más funciones, cargar tipografías, textos, ficheros XML, vídeos, shaders, definiciones de cuerpos físicos, binarios,...

Ahora vamos a añadir una pantalla de carga para que el jugador esté informado del progreso de la carga. Usaremos un rectángulo, veremos las formas primitivas en el siguiente tutorial.

function preload(){
    var progress = game.add.graphics(0,0);
    game.load.onFileComplete.add(function(prg){
        progress.beginFill(0xFF3300);
        progress.drawRect(0,0, prg*4.8,100);
        progress.endFill();
    });
    game.load.image....
    ....
}
Esta barra mostrará una barra en la parte superior que irá avanzando hasta llenar el ancho de la pantalla.

Instalando Phaser.js

Estas a punto de proseguir en tu aventura vital con algo que seguro, te ha rondado muchas veces la cabeza. Tu propio juego. Quizá ya hayas hecho alguno, pero por alguna razón te has interesado en Phaser.js. Nosotros creemos que es de lo mejorcito que hay. ¿Ya sabes todo en lo que Phaser.js destaca? Revisa este artículo si no lo tienes claro. Ahora vamos a enseñarte como instalar Phaser.

Phaser.js es una librería JavaScript como otra cualquiera

 Esto es importante. Quiere decir que hay muchas opciones de instalar Phaser.js. La clave es que en el juego final tengamos 3 archivos mínimo.
  • Un fichero HTML. Los navegadores solo comienzan a leer HTML cuando entran a una página. El fichero HTML le puede decir al navegador que hay que cargar más archivos. En los juegos HTML5, por paradójico que pueda resultar, se usa muy poco HTML. En casi todos tus juegos puede ser el mismo.
  • Un fichero JavaScript con la lógica del juego. Es el núcleo del juego. Es de lo que hablamos en esta web, cómo programar este archivo (pueden ser varios, pero no vamos a liarnos todavía)
  • Otro fichero JavaScript con Phaser.js. En JavaScript para añadir una librería simplemente la añadimos al HTML, igual que si la hubiésemos programado nosotros. No hay diferencia.

¿Cómo se añade un fichero JavaScript a un fichero HTML?

Es muy simple. En HTML contamos con la etiqueta SCRIPT. Esta etiqueta nos permite añadir ficheros con código para que sean ejecutados. SCRIPT no solo contempla JavaScript, en algunos navegadores hay otros lenguajes como VBScript (Internet Explorer) o Dart (Chrome), pero solo JavaScript es universalmente aceptado por todos los navegadores. La etiqueta SCRIPT tiene dos modos de funcionamiento. En uno se introduce el código directamente, en otro se indica el archivo. Nosotros usaremos la segunda opción por ser más legible.

Con eso bastaría. Los archivos phaser.min.js y mijuego.js (o main.js) deben de estar en la misma carpeta que el archivo HTML.

Descargar Phaser.js, ¿qué versión elijo?

Descarga Phaser desde la web oficial. Verás que hay varias versiones.
A la izquierda puedes ver que hay versiones Stable, Beta, Antiguas y personalizadas. Nosotros siempre recomendamos usar Stable. Dentro de cada versión hay distintos botones. Descarga la versión ".min.js". Esto quiere decir que es un único archivo, que pondremos al lado del HTML. La versión ".js" funciona exactamente igual pero ocupa más espacio. Esto es porque la versión "min.js" ha sido minificada, es decir ofuscada y comprimida para ocupar menos espacio y además cargar más rápido.

Creando el espacio de trabajo del juego

La organización es vital en cualquier cosa. Si mantenemos una estructura de trabajo organizada desde el principio tendremos menos dolores de cabeza después.
 No todas las carpetas son obligatorias. Según las necesidades del juego podemos borrar carpetas. ¿Qué va en cada cosa?
  • img: Recursos visuales como texturas, imágenes vectoriales, pixel art, etc...
  • js: la lógica del juego
  • locales: traducciones del juego, en muchos casos no la necesitamos pero siempre me gusta dejarla
  • maps: niveles o mapas si estos han sido creados con un editor como Tiled
  • music: canciones de la banda sonora de nuestro juego
  • sfx: efectos de sonido, son audios de corta duración
  • ttf: tipografías
  • index.html, el HTML del juego. El navegador leerá este archivo el primero. Normalmente no necesita ser modificado entre juegos.
  • main.js, el comienzo de nuestro juego. En juegos simples puede ir todo allí, en juegos complejos puede llamar a archivos dentro de la carpeta js
  • main.css, el CSS básico para ajustar algunas opciones visuales. Normalmente no necesita ser modificado entre juegos.
  • phaser.min.js, el fichero con Phaser.js. No lo modifiques.

 El fichero index.html

 El fichero index.html es muy similar entre juegos, aquí va una versión completamente funcional.

El fichero main.css

El fichero main.css tiene como finalidad ajustar el juego a la pantalla a la perfección. Tienes que pensar que los navegadores se pensaron para manejar webs de texto, no juegos, por eso los ajustes por defecto de los navegadores no son los idóneos. Aquí tienes un archivo que podrás copiar a tu ordenador.


¡Ya tienes instalado Phaser.js y tienes hecha la estructura básica de carpetas y archivos del juego! En el siguiente tutorial veremos como iniciar Phaser.js.

viernes, 8 de julio de 2016

Transformando imágenes con ImageMagick (JPEG a PNG, SVG a PNG, ...)

ImageMagick es un estupendo programa para realizar operaciones con imágenes de forma rápida y sencilla. Una vez le cojas el tranquillo, ImageMagick se convertirá en un programa que siempre querrás llevar contigo. ImageMagick se suele usar desde la línea de comandos, no obstante existen programas gráficos de los que sin embargo no vamos a hablar aquí.

Convertir entre formatos de imagen


Uno de los usos más comunes de ImageMagick es convertir entre formatos de imagen. Podemos convertir imágenes entre prácticamente todos los formatos conocidos.


convert fichero_origen.tga fichero_destino.webp
Simplemente al especificar la extensión de ambos archivos ImageMagick los reconocerá y los convertirá.

Cambiar tamaño de una imagen

Otro uso muy común de ImageMagick es para escalar, cambiar de tamaño, una imagen. Por ejemplo, tenemos una imagen de 3000x1000 píxeles y no necesitamos tanta resolución. Para facilitar tiempos de carga en el juego podemos hacer una versión de menor resolución.


convert fichero_origen.xcf -resize 1500x500 fichero_destino.png
Si no queremos conservar la relación de aspecto de la imagen (aspect ratio) deberemos indicarlo de forma explícita.

convert fichero_origen.gif -resize 1500x1000! fichero_destino.jpg
Así la imagen se achatará o se alargará hasta ser del tamaño exacto especificado.

viernes, 1 de julio de 2016

Juego de carreras HTML5 con Phaser.js

Vamos a hacer un microjuego con Phaser.js. Va a consistir en una pista de carreras sobre la cual podemos conducir un coche. Vista ortogonal.

Primero vamos a ver los gráficos que usaremos para nuestro microjuego. Necesitamos una pista y un coche. En este caso he diseñado ambos con GIMP, os recuerdo que si vamos a hacer un juego profesional y el arte no es lo nuestro lo mejor es ir a Fiverr o a foros donde encontraremos artistas especializados en estos asuntos. La textura del césped es de MyFreeTextures y el castillo es el de Montealegre en Valladolid.
http://opengameart.org/content/castillo-de-montealegre-circuit 
http://opengameart.org/content/futuristic-racing-car

  
Ahora creamos un archivo HTML e importamos Phaser

Una vez en hayamos hecho eso en nuestro fichero de JavaScript empezamos a escribir.

var game = new Phaser.Game(800, 600, Phaser.AUTO, 'racing_game', { preload: preload, create: create, update: update });
Con eso iniciamos Phaser. Hay 3 funciones importantes en Phaser: preload, create y update. Preload se encarga de cargar todo lo necesario, Create se encargará de crear la escena jugable y Update se repetirá indefinidamente hasta que termine el juego.

function preload() {
    game.load.spritesheet('circuito','circuito.png');
    game.load.spritesheet('coche','coche.png');
}
Con esto cargamos las dos imágenes para un uso posterior.

function create() {
    var circuito = game.add.sprite(0,0,'circuito');
    coche = game.add.sprite(300,100,'coche');
}
Con esto añadimos dos sprites a la escena, cada uno de ellos con una posición X e Y y un recurso dentro de las imágenes precargada.

Conduciendo el coche

 

Ahora vamos a hacer que el coche sea "conducible". Para ello creamos una variable global llamada cursors. Luego en create la inicializaremos para que maneje las teclas cursor (arriba, abajo, izquierda, derecha). De paso creamos la variable velocidad, que iniciamos a 0;

var cursors;
var velocidad = 0;
y en create()

cursors = game.input.keyboard.createCursorKeys();
También en create iniciamos el sistema de físicas, que nos ayudará para calcular la velocidad

game.physics.startSystem(Phaser.Physics.P2JS);
game.physics.p2.enable(coche);
coche.body.angle = 90;
Ahora la función update() se encarga de manejar todo esto. Detecta si alguna tecla está pulsada y actúa en consecuencia modificando la velocidad.
  • Primero se comprueba si la tecla flecha arriba está pulsada. Si además la velocidad acumulada es menor de 400 se le suman 7. En caso contrario la velocidad disminuye.
  • Después se ajusta la velocidad en los ejes X e Y. Se usa trigonometría para ello.
  • Por último se comprueban las teclas derecha e izquierda y si alguna de ellas está pulsada se modifica su velocidad angular.

function update()
{
    if (cursors.up.isDown && velocidad <= 400) {
        velocidad+=7;
    } else {
        if (velocidad >= 7)
            velocidad -= 7;
    }
                        
    coche.body.velocity.x = velocidad * Math.cos((coche.angle-90)*0.01745);
    coche.body.velocity.y = velocidad * Math.sin((coche.angle-90)*0.01745);
                
    if (cursors.left.isDown)
        coche.body.angularVelocity = -5*(velocidad/1000);
    else if (cursors.right.isDown)
        coche.body.angularVelocity = 5*(velocidad/1000);
    else
        coche.body.angularVelocity = 0;
}
Aquí está el código completo Descargar código fuente: http://sh.st/FRhIN | http://bc.vc/VjgLlxW | http://ouo.io/YeHKk8 | http://fas.li/3x5jg | http://adf.ly/1bf2ku