Tutoriais

Desenvolvimento do jogo Breakout

Essa página apresenta o desenvolvimento do jogo Breakout para browsers.

Programando com a linguagem javascript

Vamos começar criando um arquivo em branco chamado jogo.htm
Nesse arquivo vamos digitar o código:
<html>
<body>
Daqui vai surgir o jogo
</body>
</html>

Criando o elemento canvas

Vamos apagar a frase e colocar o elemento canvas
<canvas></canvas>

Testando no navegador

Se voce 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>

Tamanho do canvas

Para setar o tamanho do canvas não se deve usar atributos css.
Deve-se usar atributos da tag. Atributos html.

Por uma razão peculiar.
<center><canvas id=canvas width=400 height=450 style='border:1px solid #4a4a4a;'></canvas></center>

Começando a desenhar

O motivo que nos leva a usar o elemento canvas é que ele possibilita desenhar na tela codificando.
Os primeiros jogos eletronicos eram em modo texto. Em seguida eram em blocos quadrados. Depois eram desenhados atraves 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'.

Desenhar no canvas

Para desenhar no canvas é preciso de um 'context'
E um id pro canvas

e 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>

Um círculo

Pra 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();

Fazendo a bolinha se mover

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 parametros 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();

Apagando o rastro da bolinha

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

Fazendo a bolinha pingar nas paredes

Pra 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>

Desenhando a barra

Iniciando a posição da barra (fora da função anda)
posicaobarra=150;
Dentro da função anda (após o código que apaga o rastro)
	canvas.fillStyle='#000000';
	canvas.fillRect(posicaobarra,430,100,20);

Fazendo a barra se mover

Pra fazer a barra se mover vamos usar o atributo onKeyDown da tag body
<body onkeyDown='movebarra(event.keyCode);'>
E vamos escrever a função movebarra
Inicialmente vamos por um alert pra 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)posicaobarra-=40;
	if(tecla==39)posicaobarra+=40;
}

Fazendo a bola pingar na barra

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>430-tamanho)
	{	dif=x-posicaobarra;
		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)
		alert('Fim de jogo');
	else
		setTimeout('anda();',10);

Desenhando um bloquinho

Pra 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);
    	}

    Fazendo a bolinha pingar e o bloco desaparecer

    	if(bloco[2])
    	{	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;
    			}
    		}
    	}

    Fazer funcionar com vários blocos

    Por enquanto fizemos o jogo funcionar com um bloco
    Mas vamos precisar de 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])
    	{	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);
    	}