codinggames

Criando inimigos e itens colecionáveis no Phaser JS - Skate Platformer Game Devlog #08

Escrito em 22 de outubro de 2020 - 🕒 3 min. de leitura

Fala galera, estou de volta com outro game devlog, demorei um pouco para fazer este tiveram algumas coisas que eu realmente não sabia fazer (e ainda não sei). Veja o video abaixo.

Agora vamos dar uma olhada no código, lembra do meu loop na variavel dataLayer? É aqui que vamos adicionar nossos novos objetos.

// in the scene create function
const dataLayer = map.getObjectLayer('data');
dataLayer.objects.forEach((data) => {
    const { x, y, name, height, width } = data;

    if (name === 'coin') {
        // TODO add coin logic here
    }

    if (['box', 'long_box'].includes(name)) {
        // TODO add box logic here
    }

    if (name === 'enemy2') {
        // TODO add enemy logic here
    }

});

A primeira coisa nova são os itens colecionáveis, que é bem simples, tudo o que eu precisei fazer foi instanciar um novo GameObject e destruí-lo quando ele colidir com o hero.

if (name === 'coin') {
    const coin = new Coin({
        scene: this,
    });
    
    this.physics.add.overlap(this.player, coin, () => {
        coin.destroy(true);
    });
}

Agora, para a caixa, eu queria que ela ficasse completamente parada, a menos que o hero começasse a empurrá-la. Se eu simplesmente habilitasse o Arcade Physics nas configurações padrão, o hero iria exercer uma força na caixa, e a caixa uma força no hero, e fica algo assim:

Física de pula-pula

Eu precisava que a caixa não exercesse nenhuma força no hero, e para fazer isso eu estou usando this.body.setAllowGravity(false) e this.body.setImmovable(true), como você pode ver abaixo:

constructor({ scene, x, y, asset, frame }) {
    super(scene, x, y, asset, frame);

    // set physics
    scene.physics.add.existing(this);
    this.body.setAllowGravity(false);
    this.body.setImmovable(true);
    this.body.setAccelerationY(
        scene.physics.world.gravity.y
    );
}

update(time, delta) {
    const gravityY = this.scene.physics.world.gravity.y;
    if (this.body.velocity.x !== 0) {
        this.body.setAccelerationY(gravityY);
    } else if (this.body.acceleration.y !== gravityY) {
        this.body.stop();
    }
}

Agora se você acha que aquela gambiarra na função update foi a pior parte, mermão, você está enganado. Deixe-me te mostrar o que chamo de “a doideira da colisão”.

if (['box', 'long_box'].includes(name)) {
    let box;
    if (name === 'box') {
        box = new Box({
            scene: this,
            x,
            y,
        });
    } else {
        box = new LongBox({
            scene: this,
            x,
            y,
        });
    }

    // Add colliders that forces the box to stop
    this.physics.add.collider(dynamicLayers.ground, box, () => {
        box.body.stop();
    });
    this.physics.add.collider(dynamicLayers.elements, box, () => {
        box.body.stop();
    });
    this.physics.add.collider(mapGroundColliders, box, () => {
        box.body.stop();
    });
    this.physics.add.collider(mapElementsColliders, box, () => {
        box.body.stop();
    });

    // Handles pushing the box
    this.physics.add.collider(box, this.player, () => {
        if (
            this.player.body.touching.right
            && box.body.touching.left
        ) {
            this.player.body.velocity.x = 30;
            box.body.setVelocityX(
                this.player.body.velocity.x
            );
        }

        if (
            this.player.body.touching.left
            && box.body.touching.right
        ) {
            this.player.body.velocity.x = -30;
            box.body.setVelocityX(
                this.player.body.velocity.x
            );
        }
    });
}

E por último o inimigo, que é praticamente o mesmo que a coin, mas ao invés de destruir o inimigo na colisão, eu faço o hero ficar piscando por uns segundos.

if (name === 'enemy2') {
    const enemy2 = new Enemy2({
       scene: this,
   });

    // add hero blinking effect
    this.physics.add.overlap(
        this.player,
        enemy2,
        (objectA, objectB) => {
            this.tweens.add({
                targets: player,
                alpha: 0,
                ease: 'Cubic.easeOut',
                duration: 120,
                repeat: 5,
                yoyo: true,
            });
        }
    );
}

E por hoje é isso! Fique ligado na próxima semana, quando vou mostrar como construir a Inteligência Artificial do inimigo. Não esqueça de curtir o meu vídeo e se inscrever no meu canal 😊.

Tags:


Publicar um comentário

Comentários

Nenhum comentário.