Contents

El jugador

El propósito

Para este juego demo, el objetivo será que un caballero consiga todas las gemas repartidas por toda la pantalla. Cada vez que recoja una gema, se le incrementará la potencia de salto. Además, cuando haya recogido 8, aparecerá una plataforma móvil que le permitirá ascender a las zonas superiores. El jugador dispondrá de tres vidas, que se irán descontando si choca con alguna de las trampas. El juego termina cuando el caballero ha recogido todas las gemas o ha perdido las vidas.

El jugador

El jugador escogido será el caballero cruzado de color azul incluido en los elementos gratuitos comentados en la clase de introducción del juego. No obstante, puedes descargar el jugador completo con todo su spritesheet ya organizado haciendo clic AQUÍ. Una vez descargado, copia el fichero blueKnight.png dentro de la ruta juegoknights/img.
Como puedes ver en la imagen anterior, el spritesheet consta de 28 imágenes repartidas en dos filas. La primera de las filas corresponde a los movimientos a la izquierda y la segunda a los movimientos a la derecha. Al programar el personaje, añadiremos todas las animaciones necesarias para cada uno de los movimientos. La forma de añadir el personaje al código es similar a la del juego sencillo que hicimos anteriormente, si bien se complica un poco más en cuanto a movimientos y controles. Añade el siguiente código a los métodos preload y create y procura comprender todos los comentarios:

    preload: function () {

        //Resto de código

        //Pre-cargo el spritesheet del jugador desde el archivo png
        juego.load.spritesheet('blueKnight', 'img/blueKnight.png', 50, 50);

    },

    create: function () {

        //Resto de código

        //Blue Knight
        this.blueKnight = juego.add.sprite(50, juego.world.height - 100, 'blueKnight'); //Añado el jugador en la posición de la puerta inferior
        juego.physics.arcade.enable(this.blueKnight); //Habilito la física para el jugador
        this.blueKnight.body.gravity.y = 800; //Añado una gravedad al jugador
        this.blueKnight.body.bounce.y = 0.2; //Añado un rebote al jugador
        this.blueKnight.body.setCircle(25,0,0); //Establezco un cuerpo circular en lugar de uno cuadrado para optimizar las colisiones (radio, offset x, offset y)
        this.blueKnight.scale.set(0.75); //Escalo el jugador al 75% porque era demasiado grande

        //Animaciones derecha
        this.blueKnight.animations.add('andarDerecha', [1, 2, 3, 4, 5, 6], 10, true);
        this.blueKnight.animations.add('saltarDerecha', [13, 14], 10, true);
        this.blueKnight.animations.add('agacharseDerecha', [15, 16], 10, true);
        this.blueKnight.animations.add('ganarDerecha', [17, 18], 10, true);
        this.blueKnight.animations.add('vidaDerecha', [19, 20, 21, 22], 10, true);
        this.blueKnight.animations.add('morirDerecha', [23, 24, 25, 26, 27], 10, true);

        //Animaciones izquierda
        this.blueKnight.animations.add('andarIzquierda', [29, 30, 31, 32, 33, 34], 10, true);
        this.blueKnight.animations.add('saltarIzquierda', [41, 42], 10, true);
        this.blueKnight.animations.add('agacharseIzquierda', [43, 44], 10, true);
        this.blueKnight.animations.add('ganarIzquierda', [45, 46], 10, true);
        this.blueKnight.animations.add('vidaIzquierda', [47, 48, 49, 50], 10, true);
        this.blueKnight.animations.add('morirIzquierda', [51, 52, 53, 54, 55], 10, true);

        //Inicializo el movimiento de los cursores del jugador
        this.cursoresBlue = juego.input.keyboard.addKeys({
            left: Phaser.KeyCode.LEFT,
            right: Phaser.KeyCode.RIGHT,
            up: Phaser.KeyCode.UP,
            down: Phaser.KeyCode.DOWN,
        });

        //Cámara
        juego.camera.follow(this.blueKnight); //Le digo a la cámara que "siga" al jugador.

    },
En este punto, tu jugador ya debería aparecer en el mapa, si bien atravesará el suelo y desaparecerá por el borde inferior del juego, ya que aún no hemos establecido las colisiones del juego. Además, tampoco se moverá, ya que aunque hemos declarado los controles para el jugador, aún no hemos programado ninguno de los movimientos.

Detección de colisiones

Para la detección de colisiones, añade las siguientes líneas a los métodos create y update:

   create: function () {

        //Resto de código

        //Colisiones del suelo
        this.mapa.setCollisionByExclusion([0],true,'suelo');
        this.suelo.enableBody = true;
        //this.suelo.debug = true; //Descomenta esta línea para comprobar si has creado el suelo correctamente

        //Colisiones de las paredes
        this.mapa.setCollisionByExclusion([0],true,'paredes');
        this.paredes.enableBody = true;

    },

   update: function () {

        //Colisiones
        this.colisionSuelo = juego.physics.arcade.collide(this.blueKnight, this.suelo);
        this.colisionParedes = juego.physics.arcade.collide(this.blueKnight, this.paredes);

    },
Actualiza ahora el juego, accede al estado Jugar y comprueba que el jugador se queda parado en el suelo más cercano.

El movimiento

Para generar el movimiento del jugador, utilizaremos una variable this.direccion que nos indique en qué dirección se está moviendo (izquierda o derecha) para reproducir la animación adecuada. Además, declararemos una función llamada movimientoBlue - a la que llamaremos desde la función update - para agrupar toda la lógica de los movimientos, que por otro lado son bastante similares a los del juego sencillo. Modifica los métodos create, update y declara la función movimientoBlue tal y como se indica a continuación:

   create: function () {

        //Resto de código

        //Dirección
        this.direccion = "Derecha";

    },

   update: function () {

        //Movimiento
        this.movimientoBlue();

    },

   movimientoBlue: function () {

        //Reseteo la velocidad del jugador y frame quieto
        this.blueKnight.body.velocity.x = 0;

        //Mover a la izquierda
        if (this.cursoresBlue.left.isDown) {

            this.direccionBlue = "Izquierda";
            this.blueKnight.body.velocity.x = -200;
            this.blueKnight.animations.play('andar' + this.direccionBlue);

        }

        //Mover a la derecha
        else if (this.cursoresBlue.right.isDown) {

            this.direccionBlue = "Derecha";
            this.blueKnight.body.velocity.x = 200;
            this.blueKnight.animations.play('andar'+this.direccionBlue);

        }

        //Quedarse quieto
        else {

            this.blueKnight.animations.stop();
            //Compruebo dirección para mostrar el frame correspondiente
            if (this.direccionBlue == "Izquierda"){
                this.blueKnight.frame = 28;
            }
            else{
                this.blueKnight.frame = 0;
            }
            //this.blueKnight.animations.play(this.direccionBlue);
        }

        if (this.cursoresBlue.up.isDown && this.colisionSuelo && !this.colisionParedes){

            this.blueKnight.animations.play('saltar'+this.direccionBlue);
            this.blueKnight.body.velocity.y = -150;


        }
        //Agacharse
        if (this.cursoresBlue.down.isDown){

            this.blueKnight.animations.play('agacharse'+this.direccionBlue);

        }

    },
En este punto, tu jugador debería moverse hacia ambos lados, saltar y agacharse. Además, se deberían reproducir las animaciones correspondientes.