Criando um jogo em Javascript [2/5] – Personagem principal

Vamos continuar a nossa versão em JavaScript do Freeway, aquele jogo do Atari da galinha atravessando a rua.

No post anterior, fizemos a rua, calçadas e faixas que ficarão como pano de fundo.

Agora colocaremos a figura do personagem principal.

Inserindo uma imagem

No Freeway criado pelo Henrique Lobo Weissmann, a galinha foi criada a partir de uma matriz de cores (ou bitmap).

Aqui, vamos tomar uma abordagem mais simples: usaremos uma imagem já pronta. Apresento-lhes a Dilminha:

Dilminha, a personagem principal

Essa imagem pode ser baixada em:
http://a-dilminha.appspot.com/dilminha.png

Nota: quem tiver os direitos autorais dessa imagem, por favor entre em contato.

Criaremos um novo Image, com a URL da imagem no atributo src:

var imagem = new Image();
imagem.src = "../../dilminha.png";

Para inserir a imagem no fundo, usaremos o contexto 2D que foi criado a partir do canvas. Passaremos a imagem para a função drawImage do contexto, além das posições iniciais (x e y) e largura e altura da imagem:

var x = 320;
var y = 400;
contexto.drawImage(imagem, x, y, imagem.width, imagem.height);

Se tentarmos executar o código acima, veremos que a imagem não foi exibida. Porque será? É que só podemos colocá-la no contexto depois dela ter sido carregada. Para isso, devemos colocar uma função na propriedade onload da imagem que será executada depois do carregamento:

imagem.onload = function(){
    contexto.drawImage(imagem, x, y, imagem.width, imagem.height);
}

O resultado do código acima está disponível em:
http://a-dilminha.appspot.com/passo-a-passo/movendo/5-figura.html

Imagem da Dilminha sobre o fundo

Movendo o personagem

Com a imagem inserida sobre o fundo, precisamos movê-la ao pressionar as setas do teclado. Para isso, vamos passar para a propriedade onkeydown do document uma função que será chamada quando algo for digitado:

document.onkeydown = function(){
    //executado quando algo for digitado...
}

Nessa função, recebemos como parâmetro um objeto que representa o evento do pressionamento de teclas. Através da propriedade which desse evento, podemos saber qual tecla foi pressionada. A seta pra esquerda tem o código 37; pra cima, o código é 38; pra direita, 39; para baixo, 40.

Os eixos x e y são contados da esquerda pra direita e de baixo pra cima. Quanto maior o valor, mais para a direita e mais para baixo estará a imagem. Por isso, mover para a direita é aumentar o valor de x; pra esquerda é diminuir. Mover para cima, é diminuir o y; pra baixo, é aumentar.

Então, ficaríamos com o código:

document.onkeydown = function(event) {
    switch(event.which) {
        case 37: //pra esquerda
            x = x - 10;
        break;
        case 38: //pra cima
            y = y - 10;
        break;
        case 39: //pra direita
            x = x + 10;
        break;
        case 40: //pra baixo
            y = y + 10;
        break;
    }
}

O resultado do código acima está disponível em:
http://a-dilminha.appspot.com/passo-a-passo/movendo/6-move.html

Mas não moveu...

Por que não moveu?

Ao executarmos o código acima, vamos perceber que a imagem não foi movida. Será que esse código não funciona?

Bom… Quando o usuário pressiona as setas do teclado, o x e o y foram atualizados. O que precisamos fazer é redesenhar a imagem periodicamente, para que as novas posições sejam exibidas.

Para executar algo periodicamente no JavaScript, devemos usar a função setInterval. Precisam ser passados como parâmetros a função que será chamada e o número de milissegundos de espera entre as chamadas.

No nosso caso, a função terá o trecho de código que desenha a imagem no contexto 2D. Serão utilizados o x e o y calculados quando o usuário pressiona alguma seta do teclado. Nosso intervalo de espera será de 50 milissegundos:

setInterval(function(){
    contexto.drawImage(imagem, x, y, imagem.width, imagem.height);
}, 50);

O resultado do código acima está disponível em:
http://a-dilminha.appspot.com/passo-a-passo/movendo/7-recarrega.html

Redesenha a imagem a cada 50 milissegundos

Limpando o fundo

Perceba na imagem anterior que é deixado um rastro de todas as posições da nossa imagem. Isso acontece porque estamos redesenhando a imagem nas novas posições se limpar as imagens anteriores.

Uma maneira de fazer isso é desenhar o fundo novamente toda vez que formos atualizar a posição da imagem.

Para poder reaproveitar o código que desenha o fundo, vamos colocá-lo dentro de uma função chamada desenhaFundo. Essa função será invocada imediatamente, logo que a página for carregada, além de periodicamente, a cada 50 ms.

Vamos aproveitar e criar uma função desenhaImagem, que será responsável por desenhar a imagem no contexto 2D. Essa função também será invocada imediatamente e periodicamente.

O código reorganizado ficaria assim:

function desenhaFundo () {
    //preenche o fundo com cinza escuro
    contexto.fillStyle = "dimgray";
    contexto.fillRect(0, 0, canvas.width, canvas.height);

    //calcada superior
    contexto.fillStyle = "lightgray";
    contexto.fillRect(0, 0, canvas.width, 80);

    //calcada inferior
    contexto.fillStyle = "lightgray";
    contexto.fillRect(0, 380, canvas.width, 100);

    //faixas
    contexto.fillStyle = "white";
    for(var i = 0; i < 25; i++){
        contexto.fillRect(i*30-5, 185, 20, 4);
        contexto.fillRect(i*30-5, 280, 20, 4);
    }
}

function desenhaImagem(){
    contexto.drawImage(imagem, x, y, imagem.width, imagem.height);
};

var imagem = new Image();
imagem.src = "../../dilminha.png";
var x = 320;
var y = 400;
imagem.onload = desenhaImagem;

//código que trata teclas pressionadas omitido...

setInterval(function(){
    desenhaFundo();
    desenhaImagem();
},50);

O resultado do código acima está disponível em:
http://a-dilminha.appspot.com/passo-a-passo/movendo/8-limpando.html

Movendo imagem depois de limpar fundo

Impondo limites

Do jeito que foi feito o código que trata as teclas digitadas, os valores de x e y são adicionados ou subtraídos indefinidamente. Isso faz com que não existam limites e a imagem desapareça da tela. Por exemplo:

Imagem quase sumindo do canto inferior direito da tela

Seria interessante que limitássemos os valores possíveis de x e y. Por exemplo, podemos definir um limite superior e fazer com que, quando ultrapassado, a imagem aparece na parte debaixo da tela. Poderíamos criar também limites horizontais: quando a imagem ultrapassar o limite da direita, aparecerá a esquerda e vice-versa. O limite inferior será fixo, não fazendo com que seja tomado um atalho para o topo da tela.

Uma implementação desses limites, seguindo as regras acima, seria:

document.onkeydown = function(event) {
    switch(event.which) {
        case 37: //pra esquerda
            x = x -10;
            //passado o limite da esquerda, aparecerá à direita
            if(x < -imagem.width) {
                x = canvas.width;
            }
        break;
        case 38: //pra cima
            y = y - 10;
            //passado o limite superior, aparecerá embaixo
            if(y <= -5) {
                y = canvas.height - imagem.height;
            }
        break;
        case 39: //pra direita
            x = x + 10;
            //passado o limite da direita, aparecerá à esquerda
            if(x > canvas.width) {
                x = -imagem.width;
            }
        break;
        case 40: //pra baixo
            y = y + 10;
            //se o novo y passou o limite inferior, desfaz a soma
            if(y > canvas.height - imagem.height + 5) {
                y -= 10;
            }
        break;
    }
}

O resultado do código acima está disponível em:
http://a-dilminha.appspot.com/passo-a-passo/movendo/9-limites.html

Limite inferior

Tem mais

Semana que vem, teremos carros que se moverão sozinhos. E iremos organizar um pouco o código. Até mais!

Anúncios

3 comentários sobre “Criando um jogo em Javascript [2/5] – Personagem principal

Deixe um comentário

Preencha os seus dados abaixo ou clique em um ícone para log in:

Logotipo do WordPress.com

Você está comentando utilizando sua conta WordPress.com. Sair / Alterar )

Imagem do Twitter

Você está comentando utilizando sua conta Twitter. Sair / Alterar )

Foto do Facebook

Você está comentando utilizando sua conta Facebook. Sair / Alterar )

Foto do Google+

Você está comentando utilizando sua conta Google+. Sair / Alterar )

Conectando a %s