Ir para conteúdo
samleo

Exemplom de jogo Snake em HTML5 com javascript

Recommended Posts

Vim postar um exemplo de jogo que fiz há alguns anos. Estou postando pra caso alguém queira estudar o código.

Eu tentei deixar o máximo de faciliadde possível pra entender. A lógica é bem simples ao meu ver.

Segue:

Copie e salve o código abaixo como snake.js

// as variáveis de "saída"
var canvas;
var context;

// as variáveis do jogo
var state = 0; // estado do jogo
var TILESIZE; // tamanho dos "tiles", apenas para desenhar na tela
var pieces; // a cobra
var apple; // a maçã
var keyUp, keyRight, keyDown, keyLeft; // teclas pressionadas ou soltas
var UP, DOWN, LEFT, RIGHT; // direção da cobra
var velX, velY; // velocidade nos eixos
var collision; // indica colisão da cabeça com alguma parte da cobra
var mapWidth, mapHeight; // dimensão do "mapa"

// as imagens
var imgApple;
var imgPiece;
var imgHead;


function loadImage ( imgUrl )
{
  var img = new Image();
  img.src = imgUrl;
  return img;
}

function Piece ( x, y, dir )
{
  this.id = -1;
  this.x = x || 0;
  this.y = y || 0;
  this.dir = dir || 0;
}

Piece.prototype = 
{
  setPos: function (x, y)
  {
    this.x = x;
    this.y = y;
  },

  randomPos: function (  )
  {
    var repeat;
    var newPos = {x:0, y:0};

    do
    {
      repeat = false;
      newPos.x = Math.floor(Math.random() * mapWidth);
      newPos.y = Math.floor(Math.random() * mapHeight);
      for (var i = 0; i < pieces.length; i++)
        if (pieces[i].id == this.id || (pieces[i].x == newPos.x && pieces[i].y == newPos.y))
          repeat = true;
    } while (repeat);

    this.x = newPos.x;
    this.y = newPos.y;
  },

  draw: function ( img )
  {
    context.drawImage(img, this.x * TILESIZE, this.y * TILESIZE);
  }
}

function keyboardDown ( event )
{
  var ev = event || window.event;

  switch (ev.keyCode)
  {
    case 37: // seta esquerda
      keyLeft = true;
      break;
    case 38: // seta para cima
      keyUp = true;
      break;
    case 39: // seta direita
      keyRight = true;
      break;
    case 40: // seta para baixo
      keyDown = true;
      break;
    case 80: // tecla p = pause game
      velX = velY = 0;
      break;
    default:
      break;
  }
}

function keyboardUp ( event )
{
  var ev = event || window.event;

  switch (ev.keyCode)
  {
    case 37: // seta esquerda
      keyLeft = false;
      break;
    case 38: // seta para cima
      keyUp = false;
      break;
    case 39: // seta direita
      keyRight = false;
      break;
    case 40: // seta para baixo
      keyDown = false;
      break;
    default:
      break;
  }
}

function gameInit (  )
{
  TILESIZE = 32;
  mapWidth = 20;
  mapHeight = 15;
  canvas = document.getElementById("canvas");
  context = canvas.getContext("2d");
  canvas.width = mapWidth * TILESIZE;
  canvas.height = mapHeight * TILESIZE;

  imgPiece = loadImage("piece.png");
  imgApple = loadImage("apple.png");
  imgHead = loadImage("head.png");
  pieces = new Array(new Piece(), new Piece(), new Piece());
  apple = new Piece();
  apple.id = -10;
  velX = velY = 0;
  collision = false;
  // direções a seguir
  UP = 0;
  RIGHT = 1;
  DOWN = 2;
  LEFT = 3;

  // inicializando a parte A - a cabeça
  pieces[2].id = 2;
  pieces[2].x = 3;
  pieces[2].y = 3;
  pieces[2].dir = RIGHT;

  // inicializando a parte B
  pieces[1].id = 1;
  pieces[1].x = 2;
  pieces[1].y = 3;
  pieces[1].dir = RIGHT;

  // inicializando a parte C - o rabo
  pieces[0].id = 0;
  pieces[0].x = 1;
  pieces[0].y = 3;
  pieces[0].dir = RIGHT;

  // escolhe as coordenadas da maçã
  apple.randomPos();

  // por fim seta o estado para 1
  state = 1;
  
  // atualiza o tamnho atual na pagina html
  document.getElementById("currSize").innerHTML = pieces.length;
  // atualiza o tamanho anterior na pagina html
  document.getElementById("lastSize").innerHTML = 0;
}

function gameReset (  )
{
  // atualiza o tamanho anterior na pagina html
  document.getElementById("lastSize").innerHTML = pieces.length;

  // retira o excesso de elementos deixa só 3 pra reiniciar
  while (pieces.length > 3)
    pieces.pop();

  velX = velY = 0;
  collision = false;

  // reinicializando as peças
  // inicializando a parte A - a cabeça
  pieces[2].id = 2;
  pieces[2].x = 3;
  pieces[2].y = 3;
  pieces[2].dir = RIGHT;

  // inicializando a parte B
  pieces[1].id = 1;
  pieces[1].x = 2;
  pieces[1].y = 3;
  pieces[1].dir = RIGHT;

  // inicializando a parte C - o rabo
  pieces[0].id = 0;
  pieces[0].x = 1;
  pieces[0].y = 3;
  pieces[0].dir = RIGHT;

  apple.randomPos();
  // atualiza o tamnho atual na pagina html
  document.getElementById("currSize").innerHTML = pieces.length;
}

function gameLoop (  )
{
  if (keyLeft)
  {
    if (pieces[pieces.length - 1].dir != RIGHT)
    {
      velX = -1;
      velY = 0;
      pieces[pieces.length - 1].dir = LEFT;
    }
  }
  else if (keyUp)
  {
    if (pieces[pieces.length - 1].dir != DOWN)
    {
      velX = 0;
      velY = -1;
      pieces[pieces.length - 1].dir = UP;
    }
  }
  else if (keyRight)
  {
    if (pieces[pieces.length - 1].dir != LEFT)
    {
      velX = 1;
      velY = 0;
      pieces[pieces.length - 1].dir = RIGHT;
    }
  }
  else if (keyDown)
  {
    if (pieces[pieces.length - 1].dir != UP)
    {
      velX = 0;
      velY = 1;
      pieces[pieces.length - 1].dir = DOWN;
    }
  }

  // atualiza as posições das pieces se estiver movendo
  if (velX != 0 || velY != 0)
  {
    for (var i=0; i < pieces.length - 1; i++)
    {
      pieces[i].x = pieces[i + 1].x;
      pieces[i].y = pieces[i + 1].y;
      pieces[i].dir = pieces[i + 1].dir;
    }
  }

  if (pieces[pieces.length - 1].x == apple.x && pieces[pieces.length - 1].y == apple.y)
  {
    pieces.push(new Piece());
    pieces[pieces.length - 1].x = apple.x;
    pieces[pieces.length - 1].y = apple.y;
    pieces[pieces.length - 1].dir = pieces[pieces.length - 2].dir;
    pieces[pieces.length - 1].id = pieces.length - 1;
    apple.randomPos();
    
    // atualiza o tamanho atual na pagina html
    document.getElementById("currSize").innerHTML = pieces.length;
  }

  // agora move a cabeça
  pieces[pieces.length - 1].x += velX;
  pieces[pieces.length - 1].y += velY;

  // depois de mover a cabeça limita o movimento no canvas
  // Para o eixo X
  if (pieces[pieces.length - 1].x >= mapWidth)
  {
    pieces[pieces.length - 1].x = 0;
    collision = true;
  }
  else if (pieces[pieces.length - 1].x < 0)
  {
    pieces[pieces.length - 1].x = mapWidth - 1;
    collision = true;
  }
  
  // Para o eixo Y
  if (pieces[pieces.length - 1].y >= mapHeight)
  {
    pieces[pieces.length - 1].y = 0;
    collision = true;
  }
  else if (pieces[pieces.length - 1].y < 0)
  {
    pieces[pieces.length - 1].y = mapHeight - 1;
    collision = true;
  }

  // se colidiu com alguma parte da cobra
  if (collision)
  {
    gameReset();
  }

  // verifica se colidiu com alguma parte da cobra
  for (var i=0; i < pieces.length - 2 && !collision; i++)
    if (pieces[pieces.length - 1].x == pieces[i].x && pieces[pieces.length - 1].y == pieces[i].y)
      collision = true;

  context.fillStyle = "#FFFFFF";
  context.fillRect(0,0,canvas.width,canvas.height);
  
  // desenha o corpo da cobra (sem a cabeça)
  for (var i=0; i < pieces.length - 1; i++)
    pieces[i].draw(imgPiece);
  // desenha a maçã
  apple.draw(imgApple);
  // desenha a cabeça
  pieces[pieces.length - 1].draw(imgHead);
}

function gameMain (  )
{
  switch (state)
  {
    case 0:
      gameInit();
      break;
    case 1:
      gameLoop();
      break;
    default:
      state = 0;
      break;
  }
}

Agora, copie e salve o código abaixo como snake.html

<!DOCTYPE html>
<html>
	<meta http-equiv="Content-Type" content="text/html;charset=utf-8"></meta>
	<head>
		<title>Jogo Snake em HTML5 - por Samuel Leonardo</title>
		<style>
			canvas
			{
   	 		padding-left: 0;
   	 		padding-right: 0;
   	 		margin-left: auto;
    			margin-right: auto;
    			display: block;
			}
		</style>
	</head>
	<body onkeydown="keyboardDown(event)" onkeyup="keyboardUp(event)" onload="setInterval('gameMain()', 130)">
		<script type="text/javascript" src="snake.js"></script>
		<div align="center">
			<p>TAMANHO ATUAL: <strong id="currSize"></strong> - TAMANHO ANTERIOR: <strong id="lastSize"></strong></p>
			<canvas id="canvas" style="border:1px solid #000000;">
			Puxa vida, deixe de ser atrasado e baixe um navegador recente com suporte a <strong>HTML5</strong>
			</canvas>
			<p>MOVER use SETAS do teclado</p>
			<a href="http://bit.ly/mais_jogos"><strong>mais jogos AQUI!</strong></a>
		</div>
	</body>
</html>

Lembrando que você precisa dessas imagens abaixo:

 

Salve todas elas e coloque tudo na mesma pasta do snake.js e snake.html

piece.png.a774edaaf96f958dfc288e22e4bb4ee9.pnghead.png.89e75154b4fe55f9c7c55063dbc0152d.pngapple.png.c34802e2f2054f53df764deb332dbd16.png

São 3 imagens separadas.

 

Depois só abrir o snake.html com um browser como o firefox.

Setas movem a snake. Como é só um exemplo pra estudo, coloquei suporte só para desktop.

Compartilhar este post


Link para o post
Compartilhar em outros sites

Crie uma conta ou entre para comentar

Você precisar ser um membro para fazer um comentário

Criar uma conta

Crie uma nova conta em nossa comunidade. É fácil!

Crie uma nova conta

Entrar

Já tem uma conta? Faça o login.

Entrar Agora

×

Informação importante

Ao usar o fórum, você concorda com nossos Termos e condições.