parte 6 – Adicionando inimigos dinamicamente no jogo via Tiled

O que veremos aqui?

Neste post, mostrarei como adicionar mais inimigos no jogo usando o Tiled Map editor que e como contabilizar as moedas pegas pelo jogador.

Como adicionar mais inimigos?

Assim como as moedas, os inimigos são objetos que serão adicionados através da criação de uma nova layer no Tiled Map Editor.

Preparando o mapa

Assim, poderemos definir todos os inimigos e seus lugares de origem. Faça isso adicionando o asset do inimigo (confira atentamente o tamanho do asset antes de inserí-lo) e então crie objetos do inimigo onde deseja que eles apareçam:
novos inimigos dinamicamente criados

O próximo passo é mudarmos o código fonte para em vez de criar um inimigo, criar vários de acordo com os objetos encontrados na camada “camadaInimigos”.

Modificando o código fonte

Modifique a função criaCenario, removendo as duas linhas que criam o grupo de inimigos (pois iremos colocá-las em outro lugar) e modifique a chamada criaInimigo para criaInimigos:


    // ... código dentro da função criaCenario

    // Remova as linhas abaixo:

    // O grupo inimigos será usado para gerenciar todos os inimigos
    inimigos = game.add.group();
    // Definimos aqui que qualquer inimigo terá um corpo,
    // ou seja, nosso personagem pode bater nele
    inimigos.enableBody = true;

    // Renomeie a função criaInimigo para criaInimigos

    // ... código dentro da função criaCenario

Apenas confirmando, a função criaCenario ficará assim:

/**
 *  Cria cenário do jogo
 */
function criaCenario() {
    // Define que vai usar a física ARCADE - fácil no jogo
    game.physics.startSystem(Phaser.Physics.ARCADE);

    // Adiciona mapa
    map = game.add.tilemap('mapa');

    // Insere tileset
    map.addTilesetImage('tileset', 'tilesCenario');

    // Define quais blocos do tileset serão de colisão
    //map.setCollision(1);
    map.setCollisionBetween(1,5);
    map.setCollisionBetween(8,12);

    layer = map.createLayer('cenario');
    layer.resizeWorld();

    // Cria o jogador
    criaJogador();

    // Chama função que cria vários inimigos
    criaInimigos();

    // Define os cursores do teclado para poder controlar o jogador
    cursors = game.input.keyboard.createCursorKeys();

    criaMoedas();
}

Agora exclua a função criaInimigo e adicione a nova função criaInimigos que irá criá-los dinamicamente:

/**
 * Função que cria o jogador
 */
function criaInimigos(){
    // O grupo inimigos será usado para gerenciar todos os inimigos
    inimigos = game.add.group();
    // Definimos aqui que qualquer inimigo terá um corpo,
    // ou seja, nosso personagem pode bater nele
    inimigos.enableBody = true;

    /**
     * Carrega moedas do grupo camadaInimigos (criado no tiled map editor) que estejam usando
     * o GID 28 (tileset número 28 é o que recém adicionamos).
     * Substitui todos os inimigos pela imagem 'inimigo' carregada em carregaAssets
     * e insere todos eles no grupo inimigos recém criado
     */
    map.createFromObjects('camadaInimigos', 28, 'inimigo', 0, true, false, inimigos);

    /**
     *  Faz cada inimigo adicionado ir em direção ao jogador
     */
    for (var i = 0; i < inimigos.length; i++){
        var inimigo = inimigos.children[i];

        inimigo.body.velocity.x -= 100;
    }
}

Se rodar o jogo neste momento, perceberá que os inimigos são criados dinamicamente, porém como estão seguindo o jogador, eles acabam se amontoando:
inimigos  dinamicos se amontoam

A solução é simples: vamos fazê-los funcionar diferente!

Mudando comportamento dos inimigos

O comportamento inicial do nosso inimigo era seguir o personagem. Agora vamos fazer com que todos os inimigos tenham um comportamento padrão que é ir de um lado para o outro.

Para isso, vamos criar uma função que detecte quando um inimigo colide com uma parede e o faça andar no sentido oposto.

Crie a função abaixo no jogo:

/**
 *  Detecta colisão entre inimigo e cenário
 */
function inimigoColidiuTile(inimigo, cenario){
    // Se o inimigo encostou em algo na esquerda, manda-o para direita
    if (inimigo.body.blocked.left){
        inimigo.body.velocity.x += 100;
    }

    // Se o inimigo encostou em algo na direita, manda-o para esquerda
    if (inimigo.body.blocked.right){
        inimigo.body.velocity.x -= 100;
    }
}

E modifique a função atualizaJogo, onde detectamos a colisão entre o inimigo e a layer. Adicione o 3º parâmetro para que quando ocorra a colisão, seja chamada a função inimigoColidiuTile.

Remova também (ou comente) a chamada para a função aproximaInimigo, que por enquanto não será mais usada.

function atualizaJogo() {
    // Esta função não será mais usada por enquanto
    // aproximaInimigo();

    game.physics.arcade.collide(jogador, layer);
    game.physics.arcade.collide(inimigos, layer, inimigoColidiuTile);
    // Demais código da função...

Agora você terá inimigos que andam sozinhos para um lado e outro:
inimigos andando corretamente

Por hoje é isto, estou reduzindo os tamanhos dos posts para deixá-los mais reaproveitáveis e fáceis de serem seguidos.

Jogo em ação

Aqui você pode ver o código que implementamos funcionando. Neste link você pode baixar esta versão do jogo:

O que vem por aí?

No próximo post veremos como contabilizar pontos com as moedas que jogador encontrar no mapa.

Até breve!

Leave a Reply

%d