Pular para o conteúdo principal

Jogo Labirinto - HTML, CSS e JavaScript - Tutorial

Jogo do Labirinto


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

Mais vistas

Autocode - Significado e Funcionalidade

O Que é Autocode? O Autocode foi uma das primeiras linguagens de programação de computador, desenvolvida em 1952 por Alick Glennie para o computador Mark 1 na Universidade

Semáforo - HTML, CSS e JavaScript - Tutorial

Semáforo Funcional: Aprenda a criar um semáforo funcional com este tutorial detalhado. Descubra como implementar a lógica de controle de um semáforo usando HTML, CSS e JavaScript.

UI vs UX - Diferenças

Entendendo as diferenças entre UI e  Ux: Quando se trata de design de produtos digitais, os termos UI e UX são frequentemente usados juntos, mas representam conceitos distintos. Embora