Jogo Labirinto:
Aprenda a desenvolver um jogo do labirinto interativo com este tutorial completo usando HTML, CSS e JavaScript. Este projeto é um jogo de labirinto muito interessante, bonito e funcional. O jogador identificado de azul e o ponto de chegada identificado de verde. Este jogo representa um labirinto, Este jogo tem um cronômetro que começa a contar assim que a página é recarregada. Tem também um contador de movimentos do jogador, tem as setas clicável nas direções direita, esquerda, cima e baixo.
Assim que o jogador chega no objetivo mostra um feedback e o jogo reinicia. Este jogo também tem um botão para reiniciar a qualquer momento e quando reinicia um labirinto diferente é gerado. Este jogo pode ser jogado tanto pelos dispositivos móveis quanto pelo computador.
Veja o Jogo do Labirinto em funcionamento neste link. Jogo do Labirinto.
Veja o vídeo no YouTube:
Começando o Tutorial:
1° Passo: Abra seu VS Code, ou qualquer IDE da sua preferência e crie três pastas com os nomes... index.html, style.css e script.js.
Logo em seguida copie o código html abaixo e cole na pasta "index.html".
<!DOCTYPE html>
<html lang="pt-br">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Jogo do Labirinto</title>
<link rel="stylesheet" href="style.css">
</head>
<body>
<h1>Jogo do Labirinto</h1>
<div class="info">
<p>Movimentos: <span id="moves">0</span></p>
<p>Tempo: <span id="time">0</span>s</p>
</div>
<div id="maze-container">
<table id="maze"></table>
</div>
<div class="controls">
<button id="up">↑</button>
<div>
<button id="left">←</button>
<button id="down">↓</button>
<button id="right">→</button>
</div>
</div>
<div class="restart-container">
<button id="restart">Reiniciar</button>
</div>
<script src="script.js"></script>
</body>
</html>
2° Passo: Copie o código abaixo e cole na pasta "style.css".
body {
font-family: Arial, sans-serif;
display: flex;
flex-direction: column;
align-items: center;
margin-top: 20px;
}
h1 {
text-align: center;
}
#maze-container {
margin-top: 20px;
display: flex;
justify-content: center;
align-items: center;
}
table {
border-collapse: collapse;
}
td {
width: 30px;
height: 30px;
border: 1px solid black;
text-align: center;
vertical-align: middle;
transition: background-color 0.3s ease;
}
.wall {
background-color: black;
}
.player {
background-color: blue;
transition: background-color 0.3s ease, transform 0.2s ease;
}
.goal {
background-color: green;
}
.controls {
display: flex;
flex-direction: column;
margin-top: 20px;
align-items: center;
}
.controls button {
width: 50px;
height: 50px;
margin: 5px;
font-size: 20px;
background-color: #ccc;
border: none;
border-radius: 5px;
cursor: pointer;
transition: background-color 0.3s;
}
.controls button:hover {
background-color: #aaa;
}
.info {
display: flex;
justify-content: space-around;
width: 100%;
max-width: 300px;
margin-bottom: 20px;
}
.restart-container {
margin-top: 20px;
}
.restart-container button {
width: 120px;
height: 50px;
font-size: 18px;
background-color: #f44336;
color: white;
border: none;
border-radius: 5px;
cursor: pointer;
}
.restart-container button:hover {
background-color: #d32f2f;
}
@media (max-width: 600px) {
td {
width: 20px;
height: 20px;
}
.controls button {
width: 40px;
height: 40px;
font-size: 18px;
}
}
3° Passo: Copie o código abaixo e cole na pasta "script.js".
document.addEventListener('DOMContentLoaded', function () {
const maze = document.getElementById('maze');
const rows = 20;
const cols = 20;
let playerPosition = { row: 0, col: 0 };
let moves = 0;
let time = 0;
let timerInterval;
// Direções possíveis para mover (cima, baixo, esquerda, direita)
const directions = [
{ row: -1, col: 0 }, // Cima
{ row: 1, col: 0 }, // Baixo
{ row: 0, col: -1 }, // Esquerda
{ row: 0, col: 1 } // Direita
];
// Função para criar o labirinto
function createMaze() {
maze.innerHTML = '';
for (let r = 0; r < rows; r++) {
let row = maze.insertRow();
for (let c = 0; c < cols; c++) {
let cell = row.insertCell();
cell.classList.add('wall'); // Todas as células começam como paredes
}
}
}
// Algoritmo backtracking para criar o labirinto com caminho garantido
function generateMaze(row, col) {
maze.rows[row].cells[col].classList.remove('wall');
const shuffledDirections = directions.sort(() => Math.random() - 0.5);
for (let direction of shuffledDirections) {
const newRow = row + direction.row * 2;
const newCol = col + direction.col * 2;
if (isValidCell(newRow, newCol)) {
maze.rows[row + direction.row].cells[col + direction.col].classList.remove('wall');
generateMaze(newRow, newCol);
}
}
}
// Verificar se a célula está dentro dos limites
function isValidCell(row, col) {
return row >= 0 && row < rows && col >= 0 && col < cols && maze.rows[row].cells[col].classList.contains('wall');
}
// Função para garantir que a célula de chegada (objetivo) seja acessível
function ensureGoalAccess() {
// Remover as paredes próximas ao objetivo
if (cols > 1) {
maze.rows[rows - 1].cells[cols - 2].classList.remove('wall'); // Célula à esquerda da célula de chegada
}
if (rows > 1) {
maze.rows[rows - 2].cells[cols - 1].classList.remove('wall'); // Célula acima da célula de chegada
}
maze.rows[rows - 1].cells[cols - 1].style.borderLeft = 'none'; // Remover borda esquerda da célula de chegada
}
// Função para mover o jogador
function movePlayer(newRow, newCol) {
const newCell = maze.rows[newRow]?.cells[newCol];
if (newCell && !newCell.classList.contains('wall')) {
maze.rows[playerPosition.row].cells[playerPosition.col].classList.remove('player');
newCell.classList.add('player');
playerPosition = { row: newRow, col: newCol };
moves++;
document.getElementById('moves').textContent = moves;
// Verificar se atingiu o objetivo
if (newCell.classList.contains('goal')) {
clearInterval(timerInterval);
alert('Parabéns! Você venceu o jogo em ' + time + ' segundos e ' + moves + ' movimentos!');
resetGame();
}
}
}
// Controle pelo teclado
document.addEventListener('keydown', function (event) {
const key = event.key;
switch (key) {
case 'ArrowUp':
movePlayer(playerPosition.row - 1, playerPosition.col);
break;
case 'ArrowDown':
movePlayer(playerPosition.row + 1, playerPosition.col);
break;
case 'ArrowLeft':
movePlayer(playerPosition.row, playerPosition.col - 1);
break;
case 'ArrowRight':
movePlayer(playerPosition.row, playerPosition.col + 1);
break;
}
});
// Controle por toque
document.getElementById('up').addEventListener('click', () => movePlayer(playerPosition.row - 1, playerPosition.col));
document.getElementById('down').addEventListener('click', () => movePlayer(playerPosition.row + 1, playerPosition.col));
document.getElementById('left').addEventListener('click', () => movePlayer(playerPosition.row, playerPosition.col - 1));
document.getElementById('right').addEventListener('click', () => movePlayer(playerPosition.row, playerPosition.col + 1));
// Função para iniciar o cronômetro
function startTimer() {
time = 0;
document.getElementById('time').textContent = time;
timerInterval = setInterval(() => {
time++;
document.getElementById('time').textContent = time;
}, 1000);
}
// Função para reiniciar o jogo
function resetGame() {
clearInterval(timerInterval); // Parar o cronômetro anterior
moves = 0;
document.getElementById('moves').textContent = moves;
// Criar um novo labirinto
createMaze();
generateMaze(0, 0);
// Remover as paredes ao redor da célula de chegada
ensureGoalAccess();
// Definir o jogador na posição inicial e o objetivo
maze.rows[0].cells[0].classList.add('player');
maze.rows[rows - 1].cells[cols - 1].classList.remove('wall');
maze.rows[rows - 1].cells[cols - 1].classList.add('goal');
playerPosition = { row: 0, col: 0 };
startTimer();
}
// Iniciar o jogo
resetGame();
// Ação para o botão de reinício
document.getElementById('restart').addEventListener('click', resetGame);
});
4° Passo: Testar o Projeto!
Agora, com os três arquivos (index.html, style.css, e script.js) criados, você pode abrir o index.html no seu navegador e ver seu projeto funcionando perfeitamente!
Se preferir os códigos estão no meu Repositório no GitHub.
Comentários
Postar um comentário
Obrigado pelo seu feedback!