terça-feira, 24 de maio de 2016

Movimentando Personagens com Javascript

Neste artigo mostraremos como controlar o movimento de um personagem por javascript utilizando as teclas do computador.

Para isso utilizaremos algumas das imagens fornecidas pelo site http://untamed.wild-refuge.net/rpgxp.php. Outros sites com imagens gratuitas são listados em nosso portal alfamídia, em http://www.alfamidia.com.br/imagens-gratis-para-jogos/.

O código utilizado é um segmento do código utilizado no curso alfamídia de criação de jogos com javascript.

Capturando eventos do teclado

Uma das formas de capturar eventos em javascript é utilizando addEventListener. O que esta função faz é associar uma função a um evento.

Observe o código abaixo:

  document.addEventListener('keydown', function(event) {

    meuCenario.move(event.keyCode);

});


No código acima estamos associando uma função, que chamará o método "move" de "meuCenario", sempre que o evento "keydown" for acionado. Este evento é chamado cada vez que uma tecla é pressionada.

O parâmetro keyCode é um código que corresponde a tecla que foi pressionada. Utilizaremos o teste de determinados valores para tratar cada uma das teclas de seta.

Exibindo a Imagem Correspondente a Ação

Para exibir uma imagem, uma das funções do javascript é o drawImage, que desenha imagens em um canvas.

A especificação da função você pode encontrar em https://developer.mozilla.org/en-US/docs/Web/API/CanvasRenderingContext2D/drawImage.

Aqui nos preocuparemos com seu uso em nosso caso específico. Para isso, vale observarmos as imagens com as quais estaremos trabalhando.


Estas imagens contem um personagem de 32x48 pixels, em 16 posições diferentes. Observem que as linhas (que chamaremos de linhas 0,1,2 e 3) representam 4 direções do personagem, e as colunas (que também identificaremos como 0,1,2 e 3) representam etapas do passo do personagem.

Observe agora, a seguir, o código do desenho que estaremos utilizando. É importante gastar um tempo para entender o que está sendo feito aqui:

this.ctx.drawImage(this.imagem, 
    this.etapaPasso*TAMANHO_CELULA, this.direcaoImagem*ALTURA_PERSONAGEM, 
    TAMANHO_CELULA, ALTURA_PERSONAGEM, 
    this.x, this.y+10,
    TAMANHO_CELULA,ALTURA_PERSONAGEM);

A versão mais simples da função drawImage utiliza, além da imagem em si, dois parâmetros para definir a posição da imagem nos eixos X e Y, conforme abaixo:

void ctx.drawImage(image, dx, dy);

Aqui estamos utilizando diversos outros parâmetros, e precisaremos entender os mesmos.  Para tanto, vale olharmos a especificação da função com seu número completo de parâmetros:

void ctx.drawImage(image, sx, sy, sWidth, sHeight, dx, dy, dWidth, dHeight);
Os parâmetros de posição x e y continuam presentes, mas são respectivamente o 6º e 7º parâmetros, dx e dy, ou seja, X e Y da posição no destino.

Os parâmetros 3º, 4º e os dois últimos se referem a largura e altura da imagem, respectivamente na imagem original e no destino. No nosso caso, como não estamos redimensionando a imagem, são iguais e representam 32 (largura do personagem) e 48 (altura do personagem).

O que realmente nos interessa são os parâmetros sx e sy. Eles representam as coordenadas x e y que vamos utilizar da imagem original. Se forem 0 e 0, basicamente estamos exibindo uma imagem de 32 por 48, fazendo o corte em 32 e 48 na imagem original.

Se sx for 32, porém, estaremos exibindo não a primeira imagem do personagem, mas sim a imagem do personagem na segunda coluna. Do mesmo modo, se sy for 48, estaremos exibindo a imagem da segunda linha.

Assim sendo, podemos agora entender os parâmetros de sx e sy utilizados. Em ambos temos um índice da imagem multiplicado por 32 ou 48.

This.etapaPasso representa, assim, um número de 0 a 3 correspondendo a etapa do passo.

This.direcaoImagem representa, um número de 0 a 3 correspondendo a direção que o personagem se move.


Gerando uma Animação

Mover o personagem sempre foi relativamente simples, após sabermos capturar o teclado. Basta mantermos uma variável com a posição X e Y, e alterá-la conforme a tecla pressionada, chamando drawImage novamente.

Mudar a posição do personagem agora torna-se simples também. Selecionando um número de 0 a 3 para this.direcaoImagem, temos cada uma das 4 direções de nosso desenho.

Gerar o movimento do personagem em si é mais complexo, já que exige a exibição de uma sequência de imagens. Existem diferentes abordagens para obter este resultado, mas, via de regra, todas exigirão o uso de funções com intervalo de tempo.

Observe o segmento de código em que implementamos a caminhada no exemplo:

  this.semiPasso = function()
  {
    var posicaoInterna_Celula = ((this.etapaPasso%4)+1)/4 * TAMANHO_CELULA;
    switch (this.iniciouDirecao)
    {
      case NORTE: this.y = this.oldy - posicaoInterna_Celula;
                  this.direcaoImagem = IMAGEM_COSTAS; break;

      case SUL:   this.y = this.oldy + posicaoInterna_Celula;
                  this.direcaoImagem = IMAGEM_FRENTE; break;

      case LESTE: this.x = this.oldx + posicaoInterna_Celula;
                  this.direcaoImagem = IMAGEM_DIREITA; break;

      case OESTE: this.x = this.oldx - posicaoInterna_Celula;
                  this.direcaoImagem = IMAGEM_ESQUERDA; break;

      default:break;
    }
    this.etapaPasso = (this.etapaPasso+1) % 4;
    if (this.etapaPasso == 0 )
    {
      this.iniciouPasso = false;
    }
  }


A função semiPasso é chamada a cada ciclo de execução do jogo, caso this.iniciouPasso seja verdadeiro. Ela é responsável por fazer o movimento do personagem da sua posição inicial até a posição final, passando pelas 4 etapas do movimento.

Além de setar a imagem correspondente a direção do movimento, ela controla this.etapaPasso, variando de 0 a 3, encerra o movimento quando atinge a etapa 3, e ainda move 1/4 de posição entre uma posição definida e a outra a cada iteração.



Juntando Tudo

Estes itens acima são as funcionalidades mais complexas e/ou novas do código. Faça o download do código e abra em seu próprio computador para testá-lo. Acompanhe os cursos gratuitos e pagos de jogos em javascript da Alfamídia, que apresentam as demais funcionalidades relevantes do programa.

Assine nossa newsletter para ser avisado quando disponibilizarmos um mini-jogo contendo este recurso. Os códigos-fonte dos jogos desenvolvidos para os cursos de criação de jogos javascript da Alfamídia são disponibilizados livremente a medida que concluídos, e podem ser utilizados em qualquer desenvolvimento de jogo, comercial ou não.


2 comentários:

  1. eu queria que meu personagem assim que fosse direcionado para uma sala ele fosse automaticamente puxado para frente assim passando na frente de outros users, como em uma fila, então eu precisava saber de um script que fizesse isso, puxasse meu personagem para frente automaticamente.

    ResponderExcluir
  2. Gostaria de estudar o código fonte. Mas o link está quebrado

    ResponderExcluir