Desenvolvimento - HTML
HTML5 Canvas: Movendo um personagem com Sprites
Veja neste artigo como trabalhar com o HTML5 Canvas e veja como movimentar um personagem usando Sprites.
por Joel RodriguesIntrodução ao HTML5 Canvas
Já sabemos que com a ascensão da HTML5 e do avanço da Javascript e CSS se tornou possível desenvolver jogos completos utilizando basicamente as web standards. Isso não indica que plataformas já consolidadas como o Flash e XNA vão cair em desuso, pelo menos não agora, mas significou um grande avanço para os entusiastas do desenvolvimento de games para web que passaram a ficar menos dependentes de outras tecnologias.
Como em qualquer jogo que utilize “chars” (personagens), um dos primeiros passos é desenhar e mover um “boneco”. Inicialmente costuma-se praticar com objetos de forma fixa (um círculo, um retângulo, etc.) e em seguida se passa a usar objetos de forma variável. Nessa categoria entram os diversos personagens do jogo, que tem sua forma alterada durante o deslocamento (para dar ideia de movimento de pernas, braços, etc.).
Algumas engines mais poderosas possuem funcionalidades para fazer essa movimentação de forma prática, fornecendo e utilizando modelos (principalmente 3D), cujos movimentos são definidos em um trabalho de modelagem do personagem. Porém, em engines mais simples (principalmente as 2D), a forma mais utilizada para se desenhar e movimentar esses personagens é utilizando SPRITES, técnica que será explicada mais adiante.
Nesse artigo veremos como utilizar essa técnica com a tag CANVAS da HTML5 e auxílio da linguagem Javascript para movimentar um personagem em uma página html.
Observação: aqui implementaremos o movimento em apenas uma direção (para a direita), que será controlado pela seta do teclado. O leitor que se interessar pode utilizar a mesma técnica para desenvolver os demais movimentos e incrementar o exemplo conforme sua necessidade.
Sprites
Sprites, como são chamados, são imagens contendo várias formas/posições de um ou vários objetos. Por exemplo, um sprite para um determinado personagem deve possuir “cenas”, posições suas se movimentando. Por exemplo, ele parado, dando um passo com a perna direita, dando um passo com a perna esquerda, etc.
A figura a seguir mostra o sprite que foi utilizado neste artigo, imagem obtida na internet.
Figura 1: Sprite utilizado
Como vemos, a imagem armazena vários momentos do deslocamento de um rapaz indo para a direita.
A técnica de utilizar sprites para dar a ideia de movimento consiste em recortar partes da imagem e desenhá-las, na área reservada para esse fim, em sequência. Para isso, as dimensões de cada parte devem ser bem definidas e conhecidas pelo programador que poderá dividir a imagem original em várias partes e usar somente aquela referente a posição atual.
Como o objetivo desse artigo não é explicar como recortar imagens usando Javascript, utilizaremos outra forma um pouco menos prática, mas que também funciona e resulta no mesmo efeito.
O que faremos é recortar as imagens previamente utilizando um editor de imagens qualquer, salvando cada posição em um arquivo separado. É importante que todas as partes tenham a mesma dimensão e que o personagem seja posicionado da mesma forma em todas elas. No caso, utilizaremos imagens de dimensões 200x340px e o posicionaremos no canto inferior esquerdo do quadro. Salvaremos então cada imagem com um número que indica a posição no deslocamento, sendo 0 (zero) a primeira onde o personagem está parado. Teremos então as imagens 0.png, 1.png, até 6.png.
O código HTML
O código HTML utilizado é bastante simples e consiste basicamente de uma tag CANVAS (além da estrutura básica da página) e referência a um arquivo Javascript que desenvolveremos posteriormente.
Listagem 1: Código HTML da página
<!DOCTYPE html> <html> <head> <meta charset="UTF-8" /> <title>Canvas</title> </head> <body> <div> <canvas id="canvas" width="1000" height="340" style="background:rgb(233,233,233)"> Se você visualizar esse texto, seu browser não suporta a tag canvas. </canvas> </div> <script type="text/javascript" src="desenhar_personagem.js"></script> </body> </html>
A referência ao script foi feita após a tag canvas para garantir que a canvas já estará carregada (ou não) quando o script for interpretado.
Usamos a cor RGB(233, 233, 233) por ser a mesma do plano de fundo da imagem que tomamos como exemplo.
Passamos então para a parte principal do código, o script Javascript que “dá vida” ao personagem.
O código Javascript
A seguir serão apresentados os vários trechos de código do arquivo desenhar_personagem.js, que deve ser salvo no mesmo diretório do html e das imagens, para facilitar a compreensão e utilização. Os códigos é apresentado em uma ordem lógica, então fica como sugestão inseri-los no arquivo na sequência em que aparecem aqui.
Listagem 2: Declaração de variáveis
var canvas;//o elemento canvas sobre o qual desenharemos var ctx;//o "contexto" da canvas que será utilizado (2D ou 3D) var dx = 50;//a taxa de variação (velocidade) horizontal do objeto var x = 30;//posição horizontal do objeto (com valor inicial) var y = 0;//posição vertical do objeto (com valor inicial) var WIDTH = 1000;//largura da área retangular var HEIGHT = 340;//altura da área retangular var tile1 = new Image();//Imagem que será carregada e desenhada na canvas var posicao = 0;//Indicador da posição atual do personagem var NUM_POSICOES = 6;//Quantidade de imagens que compõem o movimento
Todas as linhas da listagem acima estão comentadas, explicando cada variável declarada, então dispensa maiores detalhes.
Listagem 3: Função KeyDown
function KeyDown(evt){ switch (evt.keyCode) { case 39: /*seta para direita*/ if (x + dx < WIDTH){ x += dx; posicao++; if(posicao == NUM_POSICOES) posicao = 1; } break; } }
Essa função será utilizada para tratar o evento Key Down da página. Como foi dito anteriormente, apenas a seta para a direita foi utilizada para movimentar a o personagem na tela.
Primeiramente verificamos se o movimento está dentro da área reservada, caso esteja, aumentamos as variáveis que indicam a posição horizontal e o estado do “boneco”. Caso o estado do personagem seja o último da sequência de imagens, voltamos para o estado inicial, mantendo assim um movimento cíclico.
Listagem 4: Função Desenhar
function Desenhar() { tile1.src = posicao+".png"; ctx.drawImage(tile1, x, y); }
Nessa função utilizamos a variável que indica a posição/estado do personagem e a utilizamos para carregar a respectiva imagem (0, 1, 2...). Em seguida, com a função drawImage do objeto ctx, desenhamos a imagem na área reservada nas coordenas x e y.
Listagem 5: Função LimparTela
function LimparTela() { ctx.fillStyle = "rgb(233,233,233)"; ctx.beginPath(); ctx.rect(0, 0, WIDTH, HEIGHT); ctx.closePath(); ctx.fill(); }
A função LimparTela, como o nome sugere, é usada para limpar o “buffer”, ou seja, redesenhar o plano de fundo da área retangular para que se possa desenhar novamente o personagem sobre ela. Essa função será usada continuamente para que a tela seja limpa e redesenhada, dando a ideia de movimento.
Listagem 6: Função Atualizar
function Atualizar() { LimparTela(); Desenhar(); }
Essa função é responsável por executar o processo de desenho, chamando as funções LimparTela e Desenhar, nessa ordem. A função atualizar será invocada repetidas vezes, em intervalos de tempo definidos a seguir.
Listagem 7: Função Iniciar
function Iniciar() { canvas = document.getElementById("canvas"); ctx = canvas.getContext("2d"); return setInterval(Atualizar, 100); }
Na Listagem 7 temos a função Iniciar, responsável por instanciar os objetos utilizados em todo o código e definir a chamada contínua à função Atualizar. Usando a função setInterval, fazemos com que a Atualizar seja invocada a cada 100 milissegundos, fazendo com que a tela se mantenha atualizada.
Em situações reais, esse intervalo é bem menor, na faixa de 10 ou até 1 milissegundo.
Listagem 8: Iniciando a execução do código
window.addEventListener('keydown', KeyDown); Iniciar();
A primeira linha de código da listagem acima faz com que a função KeyDown previamente definida seja adicionada como “event handler” do evento keydown da janela.
Em seguida chamamos a função Iniciar que, como visto anteriormente, dá início a todo o processo.
Tendo salvo os arquivos html e js juntamente com as imagens, e abrindo o documento no browser, teremos o seguinte resultado.
Figura 2: Personagem desenhado em movimento
É possível que ocorram pequenos “atrasos” no desenho e algumas atualizações visíveis da imagem, isso é corrigido com técnicas de buffer muito aplicadas no desenvolvimento de jogos, mas que não serão apresentadas aqui.
Conclusão
O objetivo desse artigo foi de apresentar uma forma de desenhar e movimentar um personagem na tela, usando a tag CANVAS da HTML5 com o auxílio de Javascript.
Como sugestão de leitura complementar ficam alguns links de outros artigos que também utilizam esses recursos para fins semelhantes:
- Movendo Objetos com Canvas
- Desenhando um Mapa 2d com Javascript
- Desenhando um mapa isométrico em HTML
Para fazer o download do código-fonte utilizado nesse exemplo, basta clicar aqui
Agradeço a atenção do leitor e até a próxima.