codinggames

Criando inteligência artificial (AI) dos inimigos no Phaser JS - Skate Platformer Game Devlog #09

Escrito em 30 de outubro de 2020 - 🕒 2 min. de leitura

Fala galera! Para o game devlog de hoje, vou mostrar mais detalhes da AI dos inimigos que implementei.

Eu decidi criar algumas mixin functions para a lógica de inteligência artificial, o que significa que preciso chamar a função dando bind à classe que está chamando ela, para isso, estou usando o “bind operator” do ES7 para que eu possa chamar a função tipo this::someExternalFunction(). Outra maneira de fazer isso seria executando Object.assign(this, { someExternalFunction }) dentro do constructor, e então chame a função como se ela fosse um método de classe, tipo this.someExternalFunction(), desse jeito você não precisa usar o bind operator.

update(time, delta) {
    this::platformWalkingBehavior();
}

Para a lógica de dentro do platformWalkingBehavior, eu fiz da maneira mais simples possível, mas ainda preciso melhorar ela um pouco para ter uma eficiência melhor quando muitos inimigos estão na tela. Primeiro eu verifico se o inimigo tem um tile de chão colidível na frente dele, se tiver, significa que pode continuar andando. Eu também verifico se há algum tile colidível bem na frente do inimigo, se houver, significa que o inimigo deve virar e andar na outra direção. Veja o código abaixo:

function platformWalkingBehavior() {
    // checks if the next ground tile is collidable
    const nextGroundTile = isNextGroundTileCollidable(
        this,
        this.touchingDownObject.layer.tilemapLayer,
        this.body.velocity.x > 0 ? 'right' : 'left'
    );

    // checks if the next tile is collidable
    const nextTile = isNextTileCollidable(
        this,
        this.touchingDownObject.layer.tilemapLayer,
        this.body.velocity.x > 0 ? 'right' : 'left'
    );

    if (!nextGroundTile || nextTile) {
        this.body.setVelocityX(
            -this.body.velocity.x
        );
    }
}
const isNextGroundTileCollidable = (
    gameObject,
    dynamicLayer,
    direction = FACING_RIGHT
) => {
    const { width } = gameObject.getBounds();
    const { x, y } = gameObject;
    const posX = direction === FACING_RIGHT ? x + width : x - 0.5;
    const tile = dynamicLayer.getTileAtWorldXY(posX, y + 0.5);
    return tile?.properties?.collideUp;
};

const isNextTileCollidable = (
    gameObject,
    dynamicLayer,
    direction = FACING_RIGHT
) => {
    const { width, height } = gameObject.getBounds();
    const { x, y } = gameObject;
    const posX = direction === FACING_RIGHT ? x + width : x - 0.5;
    const tile = dynamicLayer.getTileAtWorldXY(posX, y - 0.5);
    if (direction === FACING_RIGHT) {
        return tile?.properties?.collideLeft;
    }

    return tile?.properties?.collideRight;
};

E é assim que fica no jogo:

Enemy walking on platform

Por hoje é isso, não esqueça de curtir meu vídeo e se inscrever no meu canal.

Tags:


Publicar um comentário

Comentários

Nenhum comentário.