Como fazer um jogo em JavaScript com a tag canvas

[download id=”396″]

Esse tutorial apresenta uma maneira de desenvolver o jogo pong. Um jogo básico e simples.
Vamos começar criando um arquivo em branco chamado jogo.htm. Nesse arquivo vamos digitar o código:

<!doctype html>
<html>
    <body>
        Daqui vai surgir o jogo
    </body>
</html>

Vamos apagar a frase e colocar o elemento canvas

<canvas></canvas>

Se você salvar o arquivo e clicar duas vezes sobre ele, o navegador irá exibir uma página em branco.
Mas o canvas está lá…
Para deixar ele visível vamos colocar uma borda:

<canvas style="border:1px solid #4a4a4a;"></canvas>

Para o jogo ficar de um jeito legal vamos colocar o canvas no meio da tela e dar o tamanho 400x450px
O motivo que me levou a usar o elemento canvas é que ele possibilita desenhar na tela codificando… escrever ‘desenhe uma linha azul;’ ou ‘desenhe um quadrado no canto’
Os primeiros jogos eletrônicos eram em modo texto. Em seguida eram em blocos quadrados. Depois eram desenhados através de codificação… Depois vieram os bmp os gif os jpg… os 3d…
Mas esse jogo é da época do quadrado
E usa o canvas que é um elemento que ‘emula’ um recurso inventado na época do ‘desenhar com código’

Quando fiz esse jogo no canvas pela primeira vez em 2010 eu estava acompanhando o surgimento do html5 e li sobre o canvas e sobre como era possível desenhar nele. O jogo foi resultado de testes que começaram com a pergunta: ‘Como eu desenho uma bola nesse canvas?’
Eu pesquisei… em vários sites e tutoriais… inclusive no site do w3c e w3schools

Para desenhar no canvas eu preciso de um ‘context’
Para isso eu dou um id pro canvas que criei… e uso JavaScript

<html>
<body>
    <center><canvas id=canvas width=400 height=450 style='border:1px solid #4a4a4a;'></canvas></center>
    <script>
        canvas=document.getElementById('canvas').getContext('2d');
    </script>
</body>
</html>

Para desenhar o círculo em vermelho dentro do canvas em preciso de algumas propriedades do ‘context’… alguns métodos e atributos:
fillStyle
beginPath();
arc();
fill();

canvas.fillStyle='#ff0000'; 
canvas.beginPath(); 
canvas.arc(50,125,16,0,Math.PI*2,false); 
canvas.fill();

Recomendo que vc entenda esses parâmetros.

Vamos usar a função setTimeout();
Pegar esse código que desenha a bolinha e fazer ele ser executado a cada 10 milissegundos.
E mudar os dois primeiros parâmetros da função arc para variáveis x e y, e incrementar essas variáveis cada vez para a bolinha se mover.

x=30;
y=15;
function anda()
{	
    x+=2;
    y+=2;
    canvas.fillStyle='#ff0000';
    canvas.beginPath();
    canvas.arc(x,y,16,0,Math.PI*2,false);
    canvas.fill();
    setTimeout('anda();',10);
}
anda();
canvas.fillStyle='#ffffff'; 
canvas.fillRect(0,0,400,450);

Para isso vamos precisar de novas variáveis dx e dy que vão armazenar quanto a bolinha avança (ou retrocede) no eixos x e y
Vamos mudar o valor de dx e de dy quando a bolinha pingar na parede… quando ela chegar no chão o dx vai mudar de +2 para -2

<script>
canvas=document.getElementById('canvas').getContext('2d');
x=20;
y=200;
tamanho=10;
dx=2;
dy=2;
function anda()
{	
    x+=dx;
    y+=dy;
    if(x<tamanho)dx*=-1;
    if(y<tamanho)dy*=-1;
    if(x>400-tamanho)dx*=-1;
    if(y>450-tamanho)dy*=-1;
    canvas.fillStyle='#ffffff';
    canvas.fillRect(0,0,400,450);
    canvas.fillStyle='#ff0000';
    canvas.beginPath();
    canvas.arc(x,y,tamanho,0,Math.PI*2,false);
    canvas.fill();
    setTimeout('anda();',10);
}
anda();
</script>
barrax=150;
canvas.fillStyle='#000000'; 
canvas.fillRect(barrax,430,100,20);

Para fazer a barra se mover vamos usar o atributo onKeyDown da tag body

<body onkeyDown='movebarra(event.which);'>

E vamos escrever a função movebarra
Inicialmente vamos por um alert para identificar o código de cada tecla

function movebarra(tecla)
{	
    alert(tecla);
}

E agora vamos fazer a barra se mover

function movebarra(tecla)
{	
    /*alert(tecla);*/
    if(tecla==37)barrax-=40;
    if(tecla==39)barrax+=40;
}

Quando a bola acertar a barra a bola deve voltar a subir… E dependendo de que parte da barra a bola acertar a bola deve voltar em um certo ângulo
Vamos modificar a função anda

if(y <450-tamanho)setTimeout( 'anda();',10);
else alert('Fim de jogo');
 if(y>430-tamanho)
{	
    var dif=x-barrax;
    if(dif>-10&&dif<110)
    {	
        dy*=-1;
        if(dif>-10&&dif<15)dx=-3;
        if(dif>=15&&dif<50)dx=-2;
        if(dif>=50&&dif<85)dx=2;
        if(dif>=85&&dif<110)dx=3;
        y=430-tamanho;
    }
}

O código até aqui fica:

<!doctype html>
<html>
<body onkeyDown='movebarra(event.which);'>
<center><canvas id=canvas width=400 height=450 style='border:1px solid #4a4a4a;'></canvas></center>
<script>
canvas=document.getElementById('canvas').getContext('2d');
x=20;
y=200;
tamanho=10;
dx=2;
dy=2;
barrax=150;
function anda()
{	
    x+=dx;
    y+=dy;
    if(x<tamanho)dx*=-1;
    if(y<tamanho)dy*=-1;
    if(x>400-tamanho)dx*=-1;
    if(y>450-tamanho)dy*=-1;
    canvas.fillStyle='#ffffff';
    canvas.fillRect(0,0,400,450);
    canvas.fillStyle='#000000';
    canvas.fillRect(barrax,430,100,20);
    canvas.fillStyle='#ff0000';
    canvas.beginPath();
    canvas.arc(x,y,tamanho,0,Math.PI*2,false);
    canvas.fill();
    if(y>430-tamanho)
    {	
        var dif=x-barrax;
        if(dif>-10&&dif<110)
        {	dy*=-1;
            if(dif>-10&&dif<15)dx=-3;
            if(dif>=15&&dif<50)dx=-2;
            if(dif>=50&&dif<85)dx=2;
            if(dif>=85&&dif<110)dx=3;
            y=430-tamanho;
        }
    }
    if(y<450-tamanho)setTimeout('anda();',10);
    else alert('Fim de jogo');
}
anda();
function movebarra(tecla)
{	
    /*alert(tecla);*/
    if(tecla==37)barrax-=40;
    if(tecla==39)barrax+=40;
}
</script>
</body>
</html>

Para começar vamos apenas desenhar um bloquinho.
Vamos criar uma variável bloco que será um array com três índices:

 

  • A posição x do bloco
  • A posição y
  • Se o bloco deve ser exibido (começa com true e fica false assim que a bola atingir)
bloco=[10,20,true];
if(bloco[2])
{	
    canvas.fillStyle='#0000ff';
    canvas.fillRect(bloco[0],bloco[1],50,20);
}
if(bloco[2])
{	
    var dif=y-bloco[1]-tamanho;
    if((dy<0&&(dif>0&&dif<20))||(dy>0&&(dif<0&&dif>-20)))
    {	if(x>bloco[0]&&x<bloco[0]+50)
        {	dy*=-1;
            bloco[2]=false;
        }
    }
}

Por enquanto fizemos o jogo funcionar com um bloco
Vamos transformar em um array de blocos
Vários blocos
Vamos colocar antes da declaração do x=20 e y=200 esse trecho de código que inicializa o array de blocos:

blocos=[]; 
for(x=0;x<8;x++)for(y=0;y<5;y++)blocos.push([x*50,y*20,true]);

E vamos ‘refatorar’ o código… transformar todas a ocorrencias de bloco em blocos[indice]:

for(c=0;c<blocos.length;c++)if(blocos[c][2])
{	
    var dif=y-blocos[c][1]-tamanho;
    if((dy<0&&(dif>0&&dif<20))||(dy>0&&(dif<0&&dif>-20)))
    {	if(x>blocos[c][0]&&x<blocos[c][0]+50)
        {	blocos[c][2]=false;
            dy*=-1;
        }
    }
}
for(c=0;c<blocos.length;c++)if(blocos[c][2])
{	
    canvas.fillStyle='#0000ff';
    canvas.fillRect(blocos[c][0],blocos[c][1],50,20);
}

O código completo fica:

<!doctype html>
<html>
<body onkeyDown='movebarra(event.which);'>
<center><canvas id=canvas width=400 height=450 style='border:1px solid #4a4a4a;'></canvas></center>
<script>
canvas=document.getElementById('canvas').getContext('2d');
blocos=[];
for(x=0;x<8;x++)for(y=0;y<5;y++)blocos.push([x*50,y*20,true]);
x=20;
y=200;
tamanho=10;
dx=2;
dy=2;
barrax=150;
function anda()
{	
    x+=dx;
    y+=dy;
    if(x<tamanho)dx*=-1;
    if(y<tamanho)dy*=-1;
    if(x>400-tamanho)dx*=-1;
    if(y>450-tamanho)dy*=-1;
    canvas.fillStyle='#ffffff';
    canvas.fillRect(0,0,400,450);
    canvas.fillStyle='#000000';
    canvas.fillRect(barrax,430,100,20);
    canvas.fillStyle='#ff0000';
    canvas.beginPath();
    canvas.arc(x,y,tamanho,0,Math.PI*2,false);
    canvas.fill();
    for(c=0;c<blocos.length;c++)if(blocos[c][2])
    {	
        canvas.fillStyle='#0000ff';
        canvas.fillRect(blocos[c][0],blocos[c][1],50,20);
    }
    for(c=0;c<blocos.length;c++)if(blocos[c][2])
    {	
        var dif=y-blocos[c][1]-tamanho;
        if((dy<0&&(dif>0&&dif<20))||(dy>0&&(dif<0&&dif>-20)))
        {	
            if(x>blocos[c][0]&&x<blocos[c][0]+50)
            {	blocos[c][2]=false;
                dy*=-1;
            }
        }
    }
    if(y>430-tamanho)
    {	
        var dif=x-barrax;
        if(dif>-10&&dif<110)
        {	
            dy*=-1;
            if(dif>-10&&dif<15)dx=-3;
            if(dif>=15&&dif<50)dx=-2;
            if(dif>=50&&dif<85)dx=2;
            if(dif>=85&&dif<110)dx=3;
            y=430-tamanho;
        }
    }
    if(y<450-tamanho)setTimeout('anda();',10);
    else alert('Fim de jogo');
}
anda();
function movebarra(tecla)
{	
    /*alert(tecla);*/
    if(tecla==37)barrax-=40;
    if(tecla==39)barrax+=40;
}
</script>
</body>
</html>

Como fazer um jogo em JavaScript

[download id=”285″]

Olá Pessoal do MundoJs !

Esse é um artigo/tutorial sobre mecanismos básicos de jogos em javascript

Será apresentada uma maneira bem básica de como fazer um jogo da cobrinha em javascript. É um jogo para ser jogado no browser/navegador (chrome/firefox/explorer) mas não funciona em tablets e celulares porque precisa do teclado…

Vamos começar criando um arquivo .html em branco. E logo em seguida escrever um pouco de html:

<html>
<body>
    <div id=principal></div>
    <script>
        document.getElementById('principal').innerHTML='Daqui surge o jogo';
    </script>
</body>
</html>

Até aqui sem maiores surpresas… um simples arquivo sem muita complicação.

Logo em seguida vamos criar o tabuleiro por onde a cobra irá se movimentar:

<html>
<body>
    <div id=principal></div>
    <script>
    tabuleiro="<table align=center border=1>";
    for(x=0;x<10;x++){
        tabuleiro+="<tr>";
        for(y=0;y<10;y++)
            tabuleiro+="<td>"+x+"_"+y+"</td>";
        tabuleiro+="</tr>";
    }
    document.getElementById('principal').innerHTML=tabuleiro+"</table>";
    </script>
</body>
</html>

Vamos dar um id para cada celula do tabuleiro:

for(y=0;y<10;y++){
    tabuleiro+="<td id=td"+x+"_"+y+" style='width:30px; height:30px;'> </td>";
}

Vamos ‘pintar’ uma celula do tabuleiro:

document.getElementById('td3_3').style.background="#333333";

Vamos criar uma variavel cobra[] que armazena a coordenada (x,y) da cobra:

cobra=[5,0];
document.getElementById('td'+cobra[0]+'_'+cobra[1]).style.background="#333333";

Vamos fazer a cobra ‘andar’ com a função ‘setTimeout’:

function anda(){
    cobra[1]++;
    document.getElementById('td'+cobra[0]+'_'+cobra[1]).style.background="#333333";
    setTimeout('anda()',300);
}
anda();

Essa função setTimeout é a base do movimento em javascript. Existem alternativas mas essa é nativa e tem vantagens…

E vamos ‘apagar’ o rastro da cobrinha:

function anda(){
    document.getElementById('td'+cobra[0]+'_'+cobra[1]).style.background="#ffffff";
    cobra[1]++;
}

Vamos ‘interceptar/interpretar’ a tecla que o usuário aperta no teclado:

<body onKeyDown="pegadirecao(event.keyCode);">
function pegadirecao(tecla){
    alert(tecla);
}

Vamos criar uma variavel direcao que armazena/determina pra onde a cobra deve se mover:

direcao=2;
function pegadirecao(tecla){
    /*alert(tecla);*/
    if(tecla==37)direcao=0;
    if(tecla==38)direcao=1;
    if(tecla==39)direcao=2;
    if(tecla==40)direcao=3;
}

E dentro da função anda

if(direcao==0)cobra[1]--;
if(direcao==1)cobra[0]--;
if(direcao==2)cobra[1]++;
if(direcao==3)cobra[0]++;

vamos criar a maçã:

mx=parseInt(Math.random()*10);
my=parseInt(Math.random()*10);

E na função ‘anda()’

document.getElementById('td'+mx+'_'+my).style.background="#ff3333";

Vamos fazer a maçã ser gerada novamente:

if(mx==cobra[0]&&my==cobra[1]){
    mx=parseInt(Math.random()*10);
    my=parseInt(Math.random()*10);
    cobra[cobra.length]=[10,10];
}

Agora vem a parte mais sofisticada do jogo. Vamos transformar a variável cobra de um array para um array de arrays. Até agora a variavel cobra armazenava um ponto. A partir daqui essa variavel armazenará um array de pontos…

cobra=[[5,0]];
function anda(){
    document.getElementById('td'+cobra[cobra.length-1][0]+'_'+cobra[cobra.length-1][1]).style.background="#ffffff";
    if(mx==cobra[cobra.length-1][0]&&my==cobra[cobra.length-1][1]){
        mx=parseInt(Math.random()*10);
        my=parseInt(Math.random()*10);
        cobra[cobra.length]=[10,10];
    }
    if(direcao==0)cobra[0][1]--;
    if(direcao==1)cobra[0][0]--;
    if(direcao==2)cobra[0][1]++;
    if(direcao==3)cobra[0][0]++;
    document.getElementById('td'+cobra[0][0]+'_'+cobra[0][1]).style.background="#333333";
    document.getElementById('td'+mx+'_'+my).style.background="#ff3333";
    setTimeout('anda()',300);
}

Para fazer a cobra se movimentar devemos passar os valores de cada coordenada de cada ‘gomo’ da cobra para o ‘gomo de traz’:

for(x=cobra.length-1;x>0;x--){
    cobra[x][0]=cobra[x-1][0];
    cobra[x][1]=cobra[x-1][1];
}

Agora só falta fazer função que executará quando a cobra ‘morrer’:

vivo=true;
if(vivo)setTimeout('anda()',300);
else alert('Fim de jogo');
for(x=1;x<cobra.length;x++){
    if(cobra[0][0]==cobra[x][0]&&cobra[0][1]==cobra[x][1])vivo=false;
    if(cobra[0][0]<0||cobra[0][1]<0||cobra[0][0]>9||cobra[0][1]>9)vivo=false;
}

O código completo fica:

<html>
<body onKeyDown="pegadirecao(event.keyCode);">
<div id=principal></div>
<script>
    tabuleiro="<table align=center border=1>";
    for(x=0;x<10;x++){
        tabuleiro+="<tr>";
        for(y=0;y<10;y++)
            tabuleiro+="<td id=td"+x+"_"+y+" style='width:30px; height:30px;'> </td>";
        tabuleiro+="</tr>";
    }
    document.getElementById('principal').innerHTML=tabuleiro+"</table>";
    cobra=[[5,0]];
    direcao=2;
    mx=parseInt(Math.random()*10);
    my=parseInt(Math.random()*10);
    vivo=true;
    function anda(){
        document.getElementById('td'+cobra[cobra.length-1][0]+'_'+cobra[cobra.length-1][1]).style.background="#ffffff";
        if(mx==cobra[cobra.length-1][0]&&my==cobra[cobra.length-1][1]){
            mx=parseInt(Math.random()*10);
            my=parseInt(Math.random()*10);
            cobra[cobra.length]=[10,10];
        }
        for(x=cobra.length-1;x>0;x--){
            cobra[x][0]=cobra[x-1][0];
            cobra[x][1]=cobra[x-1][1];
        }
        if(direcao==0)cobra[0][1]--;
        if(direcao==1)cobra[0][0]--;
        if(direcao==2)cobra[0][1]++;
        if(direcao==3)cobra[0][0]++;
        for(x=1;x<cobra.length;x++)if(cobra[0][0]==cobra[x][0]&&cobra[0][1]==cobra[x][1])vivo=false;
        if(cobra[0][0]<0||cobra[0][1]<0||cobra[0][0]>9||cobra[0][1]>9)vivo=false;
        document.getElementById('td'+cobra[0][0]+'_'+cobra[0][1]).style.background="#333333";
        document.getElementById('td'+mx+'_'+my).style.background="#ff3333";
        if(vivo)setTimeout('anda()',300);
        else alert('Fim de jogo');
    }
    anda();
    function pegadirecao(tecla){
        /*alert(tecla);*/
        if(tecla==37)direcao=0;
        if(tecla==38)direcao=1;
        if(tecla==39)direcao=2;
        if(tecla==40)direcao=3;
    }
</script>
</body>
</html>