miércoles, 31 de diciembre de 2014

Phaser 2014

como hacer juego con html5

Es increible lo rapido que se ha pasado el tiempo , desde cuando comenze el blog alla en los primeros meses del año y mirar que este ya ha llegado a su fin.

La verdad esto fue muy divertido e inriquecedor , poder compartir conocimiento, aficiones etc..,con tantas personas fue genial , muchas gracias a todas las personas que me escribieron que se comunicaban conmigo, a todos los que leen este blog, ya que son los pilares para continuar con todo esto.


 Este año lleno de tanto codigo en el cual aprendí aun mas y que intente compartir con ustedes. Espero que haya sido de utilidad y que los animara a no darse por vencido , animarlos a que si les gustaba esto que al menos lo intentaran. 

Si lograste seguir hasta este punto me alegro mucho, y si no pues nunca es tarde para intentarlo, los responsables de que nuestros sueños se cumplan somos nosotros mismos. 

Me quedaron muchos temas por tocar y que queria compartir pero bueno el año que viene si DIOS nos da fuerza sera genial. Y para terminar el año como debe ser vamos a repasar el funcionamiento del codigo anterior el minijuego que mostre. 

Comenzamos: 

Creamos las variables a utilizar.
 
var estrellas,balon,stars,flecha;
 
Creamos una nueva instancia de Phaser.Game: 

var game = new Phaser.Game(400, 400, Phaser.AUTO, 'ejemplo', { preload: preload, create: create,update:update});

Cargamos las imagenes necesarias: 

function preload() {
game.load.image("star","S.png");
game.load.image("ball","b.png");
game.load.image("a","arrow.png");
};

En la funcion create: 

En la funcion create:
En la funcion create:
En la funcion create:
En la funcion create:
En la funcion create:
function create() {
game.stage.setBackgroundColor(0x22aaff);
    game.physics.startSystem(Phaser.Physics.ARCADE);
    stars= game.add.group();
    stars.enableBody = true;
    stars.physicsBodyType = Phaser.Physics.ARCADE;

balon = game.add.sprite(200,350,"ball");
game.physics.arcade.enable(balon)
balon.body.collideWorldBounds = true;
balon.body.bounce.setTo(1, 1);
flecha =null
game.input.onDown.add(presiona, this);
game.input.onUp.add(suelta, this);
presionado=false;
tiempoSostenido=0;
estado = null;
comenzar(0);
};
Le agregamos un color azul a nuestro fondo, inicializamos el sistemas de fisica, como las estrellas son varias del mismo tipo entonces creamos un grupo, activamos la fisicas en todos los elementos de dicho grupo. 


Mediante un ciclo For anidado(uno dentro del otro) el cual se ejecuta de la siguiente forma: 

for(var xx=0; xx<4 ; xx++){
    for (var yy=0; yy<4;yy++){
        estrella=stars.create(70+xx*60,yy*50,"star");
     estrella.width=50;
     estrella.height=50;
    };
};


  • El For exterior se ejecuta una vez mientras que el interior cumpe el ciclo completo es decir cuatro veces, dandonos asi por cada fila cuatro estrellas(una figura 4x4).

 Luego agregamos el balon activamos la fisica , dos eventos touch(mouse)que se activan cada que se presione o suelte una funcion(callback) correspondiente sea llamada. 

Con la variable presionado comprobamos cual evento ha sido activado, con tiempoSostenido se comprueba el tiempo que tardamos con el mouse presionado, con la variable estado comprobamos si el medidor de fuerza(flecha) esta activa o no y la funcion comenzar inicializamos el valor de dicho estado. 

Aqui tenemos la funcion presiona y suelta que son llamada por el evento del mouse:

function  presiona(pointer) {
  presionado= true;
};
function suelta(pointer) {
  presionado= false;
};
function fuerza() {
  return Math.abs(((game.time.now- tiempoSostenido + 600) % 1000) -600);
};

Con la funcion fuerza hacemos un calculo para saber el tiempo que tarda el evento, esto es restando el tiempo actual menos el sostenido a esto le sumamos un valor de 600 y mediante el operador mod verificamos que el valor retornado no sobrepase los mil, recuerda que este operador nos devuelve el residuo de la division(5000%1000 nos devuelve cero), y al resultado de toda esta operacion le restamos 600 asi conseguimos el valor de la fuerza con la que sera lanzada la pelota y que este valor suba y baje de 0 a 600. 

En la funciones que crean y destruyen las flechas tenemos:

function crearFlecha() {
  flecha = game.add.sprite(0, 0, 'a');
   flecha.anchor.setTo(0.5, 0.5);
   flecha.pivot.x = -18;
  flecha.pivot.y = 30;
  balon.addChild(flecha);
}
function removerFlecha() {
  balon.removeChild(flecha);
  flecha.destroy();
}
Para crear la flecha es sencillo agregamos el sprite , modificamos la propiedad pivot que es punto por donde sera tomada al momento de que gire, aqui vemos un defecto ya que recuerda que el objeto fisico detras de la pelota es un cuadrado de ahi el motivo del giro extraño de la flecha, este objeto sera anclado a la pelota es como el hijo de la pelota asi logramos que tome una posicion relativa al padre en este caso la pelota. 

Pero esto es necesario? 

Pues lo podemos hacer normalmente agregar otro sprite pero asi es mas rapido y sencillo.
 En algun momento explique un poco sobre PIXI, rapidamente todo lo que se muestra(hijos) es agregado a un array esto es manejado por una clase DisplayManager(padre), asi tambien la clase sprite hereda de esta dandonos la capacidad de agregar hijos(chlid) a un sprite.

 Para eliminar la flecha removemos el objeto(child) de el sprite balon(padre) y usamos el metodo Destroy para eliminarlo por completo. La funcion comenzar que inicializamos en la funcion create pasandole cero como parametro comenzar(0). 

function comenzar(nuevoestado) {
  if (estado != nuevoestado) {
    if (estado === 1) {
      removerFlecha();
    } else if (estado === 0) {
      balon.body.velocity.setTo(0,0);
      crearFlecha();
      tiempoSostenido = 0;
    }
  estado = nuevoestado;
  }
}

Nada complicado solo tenemos dos valores (0:encendido,1:apagado), normalmente es al contrario (0:"no hay nada", 1:un bloque, esto refiriendo a las (tiles) esos mapas como los de mario bros).

 Primero comprbamos si el estado a cambiado es decir si es diferente, de ser asi comprobamos cual es el valor del nuevo estado si es 1 removemos la flecha y si es 0 nos aseguramos de que la velocidad de la pelota sea cero(que se haya detenido), llamamos a la funcion que crea la flecha y reiniciamos el valor del tiempoSostenido y actualizamos el valor de la variable estado asignandole el valor de la variable nuevoEstado.

 En la funcion Update: 

function update (){
game.physics.arcade.overlap(balon,stars,destruye,null,this);

 if (estado === 0) {

    if (Math.abs(balon.body.velocity.x) < 10 && Math.abs(balon.body.velocity.y) < 10) {
     comenzar(1);
   }
  } else if (estado === 1) {
    flecha.rotation = game.math.angleBetween(balon.body.x, balon.body.y, game.input.x, game.input.y) + Math.PI/2;

    if (presionado) {
      if (tiempoSostenido == 0) {
        tiempoSostenido = game.time.now;
        }else {flecha.scale.y = 1.0 + fuerza()/500 * 2;}

    }else if (tiempoSostenido != 0) {
      balon.body.velocity = game.physics.arcade.accelerationFromRotation(flecha.rotation - Math.PI/2, fuerza() + 50);
      comenzar(0);
    }
};
};

function destruye(a,b){
 b.kill();
};

Comprobamos si la pelota toca alguna estrella de ser asi llamamos a la funcion destruye donde eliminaremos dicha estrella, en cada segundo comprobamos en que estado nos encontramos, si es 0(la flecha ya ha sido creada y lanzada) y la velocidad de la pelota es inferior a 10 llamamos a la funcion estado pasando el valor 1(para que elimine la flecha). 

Si el valor del estado es 1(la pelota y flecha han sido removida debemos volver a crearla), con la propiedad rotation modificamos la posicion de la flecha para que siga al puntero del mouse esto lo calculamos con game.math.angleBetween() que es el angulo entre la pelota y la posicion del puntero. 

Ademas comprobamos si se esta presionando el mouse de ser asi comprobamos el valor de tiempoSostenido si es cero le agregamos el actual, y si no es cero pero aun se sigue presionando modificamos la escala de la flecha para que esta sea mas grande o pequeña. 

Tomamos el valor que devuelve fuerza(0 a 600) lo dividimo entre 500, lo multiplicamos por 2 y le sumamos 1.0 asi obtenemos un valor pequeño entre 0 y 3.5. 

Mientras que si no se esta presionando y el tiempoSostenido es diferente de cero lanzamos la pelota, para cualcular la aceleracion del objeto mientras lo rotamos usamos el metodo game.physics.arcade.accelerationFromRotation que devuelve un valor para ambos ejes. 

Para terminar desearles un Feliz Año,que el proximo sea infinitamente mejor y que todos nuestros se hagan realidad. 

Hasta la Proxima!!! 


 

No hay comentarios:

Publicar un comentario