Estou iniciando meus estudos com desenvolivmento de jogos em Javascript e pretendo iniciar uma série de posts relacionados ao que aprendi durante esse tempo.
Para começar, veremos um pouco da API do canvas e de como ela pode nos ajudar a desenvolver jogos em Javascript.
Porque canvas?
Falando em jogos no browser, um elemento fundamental a se entender é o canvas. Ele que vai nos permitir desenhar objetos na tela e também movimentá-los, criar animações e etc…
Além do mais, ele é compatível com os browsers mais modernos (IE9, Firefox, Safari, Chrome), e para os mais antigos, existe uma biblioteca que contorna esse problema.
Desenhos simples
Para desenhar com o canvas, primeiro precisamos do elemento no nosso HTML, como esse aqui:
<!DOCTYPE html>
<html>
<head>
<title>Canvas</title>
</head>
<body>
<canvas id="canvas" width="960" height="480">
</canvas>
<script type="text/javascript" charset="utf-8">
// Codigo aqui
</script>
</body>
</html>
Feito isso, podemos manipular o canvas através do Javascript, veja esse exemplo:
var canvas = document.getElementById("canvas");
var paper = canvas.getContext("2d");
function draw() {
paper.fillRect(10, 10, 100, 100);
}
draw();
Algumas coisas que temos que entender aqui. Primeiro, existe o elemento HTML do canvas na primeira linha. Depois, escolhemos um contexto para o nosso canvas (no caso 2d) com o getContext(). Esse contexto 2d que vai definir qual a API a ser utilizada nos nossos desenhos.
Um método dessa API é o fillRect, que basicamente desenha um retângulo na tela. Os dois primeiros parâmetros são a posição na tela, no caso X e Y, e os dois últimos são o tamanho do nosso retângulo (um quadrado, na verdade). Todos os parâmetros são em pixels.
Não vou entrar em detalhes de toda a API de desenho do canvas, mais informações você pode conferir aqui. Mas existe uma em especial que quero dar mais foco. Veja o exemplo abaixo:
function draw() {
paper.beginPath();
paper.moveTo(10, 0);
paper.lineTo(20, 30);
paper.lineTo(0, 30);
paper.closePath();
paper.stroke();
}
draw();
No exemplo acima, estamos criando um desenho mais customizado. O método beginPath() diz ao canvas que vamos começar um desenho usando as APIs do PATH, que podemos associar a um “lápis” na tela.
O moveTo() move nosso “lápis” para o ponto 10,0 (x,y). A partir do ponto 10,0, desenhamos uma linha com o método lineTo() para o ponto 20,30. Neste momento, é como se fosse desenhada uma linha mesmo. O mesmo fazemos depois para o ponto 0,30. O método closePath() fecha automaticamente nosso desenho para o ponto inicial, no caso 10,0.
O método stroke() finaliza o desenho. Se você não chamá-lo ao final, seu desenho não aparecerá na tela. Isso porque o método lineTo() apenas adiciona as coordenadas numa fila, que depois são finalmente desenhadas com o stroke().
Animando
Para darmos mais vida ao nosso player, utilizaremos dois métodos do canvas: translate e rotate.
function draw() {
paper.translate(30, 30);
paper.rotate(0.1);
//...
}
O método translate() move o canvas inteiro para a posição X,Y passada nos argumentos. Já o rotate(), gira o canvas inteiro para o ângulo passado (em radianos). Essas duas chamadas dos métodos devem ser colocadas antes do beginPath(). Se colocarmos as chamadas depois do stroke(), nada vai acontecer, porque as transformações com translate() e rotate() só afetam os próximos desenhos.
Vamos trocar a chamada do draw() no fim do nosso script para isso:
Agora você deve ter visto que nosso player se “move” na tela, mas não do jeito que esperávamos, porque o desenho antigo não é apagado da tela. Isso porque a cada 200 milisegundos estamos criando um novo desenho e não movendo o player de verdade. Para corrigir isso, chamamos o método clearRect(x, y, width, height) no início do método draw(). Esse método limpa todos os pixels dentro do retângulo passado.
O código final você pode ver abaixo:
var canvas = document.getElementById("canvas");
var paper = canvas.getContext("2d");
function draw() {
paper.clearRect(0, 0, 960, 480);
paper.translate(30, 30);
paper.rotate(0.1);
paper.beginPath();
paper.moveTo(10, 0);
paper.lineTo(20, 30);
paper.lineTo(0, 30);
paper.closePath();
paper.stroke();
}
setInterval(draw, 200);
Essa ainda não é a forma ideal de movermos nosso player na tela, principalmente porque estamos movendo o canvas inteiro e não só o player. Se tivermos outros desenhos na tela, você vai ver que eles se moverão junto com o nosso player, e isso não é o ideal. Falarei mais sobre este problema e como evitá-lo no próximo post da série.
Concluindo
Até aqui conseguimos entender um pouco do canvas, e de como sua API nos permite fazer coisas bem interessantes. Também já conseguimos ter uma boa idéia de como vai ser nosso jogo e de como podemos estruturá-lo.
No próximo post continuaremos nossa série, falando mais sobre a estrutura do nosso jogo e de como manipular nosso player com o teclado.
Até lá!