3D Maze Game Using HTML and JavaScript

0
85
3d maze game using javascript

Creating engaging browser-based games is a fantastic way to polish your programming skills. In this tutorial, we’ll walk through building a simple maze game with a 3D effect using HTML5 Canvas and JavaScript. The game involves guiding a player from the starting point to the goal, navigating through a randomly generated maze.

Features of the Maze Game

  • 3D Visual Effect: Walls, the player, and the goal have subtle gradients for a 3D appearance.
  • Random Maze Generation: Each play-through offers a unique challenge with a maze generated using recursive backtracking.
  • Keyboard Navigation: Use arrow keys to navigate the player through the maze.
  • Winning State: A congratulatory message appears when the player reaches the goal.

Game Setup

The game is built using HTML, CSS, and JavaScript. Here’s how it’s structured:

  • HTML: Defines the canvas element and layout.
  • CSS: Styles the game elements and adds 3D effects.
  • JavaScript: Implements the game logic, including maze generation, rendering, and player movement.

Follow this video for complete guidance :

Full Source Code

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Find Your Way - 3D</title>
    <style>
        body {
            text-align: center;
            font-family: Arial, sans-serif;
            background: linear-gradient(to bottom, #e0e0e0, #b0b0b0);
            margin: 0;
            padding: 0;
        }
        canvas {
            border: 10px solid #222;
            border-radius: 10px;
            background: linear-gradient(to bottom, #f4f4f4, #d4d4d4);
            box-shadow: 0px 8px 15px rgba(0, 0, 0, 0.5);
            margin: 20px auto;
            display: block;
        }
        #message {
            font-size: 2em;
            font-weight: bold;
            color: green;
            text-shadow: 2px 2px 4px rgba(0, 0, 0, 0.5);
            display: none;
        }
        h1 {
            color: #333;
            text-shadow: 1px 1px 2px rgba(0, 0, 0, 0.3);
        }
    </style>
</head>
<body>
    <h1>Find Your Way</h1>
    <div id="message">You Win!</div>
    <canvas id="gameCanvas" width="400" height="400"></canvas>
    <script>
        const canvas = document.getElementById('gameCanvas');
        const ctx = canvas.getContext('2d');
        const gridSize = 20;
        const rows = canvas.height / gridSize;
        const cols = canvas.width / gridSize;
        let player = { x: 0, y: 0 };
        let goal = { x: cols - 1, y: rows - 1 };

        let maze = [];

        // Maze Generator using Recursive Backtracking
        function generateMaze() {
            maze = Array.from({ length: rows }, () => Array(cols).fill(1)); // Fill maze with walls
            const directions = [
                { dx: 0, dy: -1 }, // Up
                { dx: 0, dy: 1 },  // Down
                { dx: -1, dy: 0 }, // Left
                { dx: 1, dy: 0 }   // Right
            ];

            // Helper to shuffle directions for random exploration
            function shuffle(array) {
                for (let i = array.length - 1; i > 0; i--) {
                    const j = Math.floor(Math.random() * (i + 1));
                    [array[i], array[j]] = [array[j], array[i]];
                }
                return array;
            }

            // Recursive function to carve paths
            function carvePath(x, y) {
                maze[y][x] = 0; // Mark cell as path
                shuffle(directions).forEach(({ dx, dy }) => {
                    const nx = x + dx * 2;
                    const ny = y + dy * 2;
                    if (nx >= 0 && ny >= 0 && nx < cols && ny < rows && maze[ny][nx] === 1) {
                        maze[y + dy][x + dx] = 0; // Remove wall between cells
                        carvePath(nx, ny);
                    }
                });
            }

            carvePath(0, 0); // Start carving from the top-left corner
            ensureGoalPath();
        }

        // Ensure the bottom-right corner is reachable
        function ensureGoalPath() {
            maze[rows - 1][cols - 1] = 0; // Ensure goal position is a path
            if (maze[rows - 2][cols - 1] === 1 && maze[rows - 1][cols - 2] === 1) {
                maze[rows - 2][cols - 1] = 0; // Create path if isolated
            }
        }

        // Draw Maze, Player, and Goal
        function drawGame() {
            ctx.clearRect(0, 0, canvas.width, canvas.height);
            for (let i = 0; i < rows; i++) {
                for (let j = 0; j < cols; j++) {
                    if (maze[i][j] === 1) {
                        // Draw walls with a 3D effect
                        ctx.fillStyle = '#444';
                        ctx.fillRect(j * gridSize, i * gridSize, gridSize, gridSize);
                        ctx.fillStyle = '#555';
                        ctx.fillRect(j * gridSize + 2, i * gridSize + 2, gridSize - 4, gridSize - 4);
                    }
                }
            }
            // Draw goal with gradient for 3D effect
            const goalGradient = ctx.createLinearGradient(
                goal.x * gridSize,
                goal.y * gridSize,
                (goal.x + 1) * gridSize,
                (goal.y + 1) * gridSize
            );
            goalGradient.addColorStop(0, '#3fa34d');
            goalGradient.addColorStop(1, '#2d7a35');
            ctx.fillStyle = goalGradient;
            ctx.fillRect(goal.x * gridSize, goal.y * gridSize, gridSize, gridSize);

            // Draw player with gradient for 3D effect
            const playerGradient = ctx.createLinearGradient(
                player.x * gridSize,
                player.y * gridSize,
                (player.x + 1) * gridSize,
                (player.y + 1) * gridSize
            );
            playerGradient.addColorStop(0, '#4a90e2');
            playerGradient.addColorStop(1, '#357abf');
            ctx.fillStyle = playerGradient;
            ctx.fillRect(player.x * gridSize, player.y * gridSize, gridSize, gridSize);
        }

        // Movement Logic
        function movePlayer(dx, dy) {
            const newX = player.x + dx;
            const newY = player.y + dy;
            if (
                newX >= 0 && newX < cols &&
                newY >= 0 && newY < rows &&
                maze[newY][newX] === 0
            ) {
                player.x = newX;
                player.y = newY;
                if (player.x === goal.x && player.y === goal.y) {
                    document.getElementById('message').style.display = 'block';
                    document.removeEventListener('keydown', handleKeyDown);
                }
            }
            drawGame();
        }

        // Key Controls
        function handleKeyDown(e) {
            if (e.key === 'ArrowUp') movePlayer(0, -1);
            if (e.key === 'ArrowDown') movePlayer(0, 1);
            if (e.key === 'ArrowLeft') movePlayer(-1, 0);
            if (e.key === 'ArrowRight') movePlayer(1, 0);
        }

        // Game Initialization
        function initGame() {
            generateMaze();
            drawGame();
            document.getElementById('message').style.display = 'none';
            player = { x: 0, y: 0 };
            document.addEventListener('keydown', handleKeyDown);
        }

        initGame();
    </script>
</body>
</html>

How to Run the Game

  • Copy the code into an .html file.
  • Open the file in your browser.
  • Use the arrow keys to guide the player to the goal.
ALSO READ  Create Sticky Notes Application using HTML, CSS and JavaScript in 5 minutes

Enhancements

  • Add Difficulty Levels: Increase maze size or player speed.
  • Timer: Introduce a countdown for added challenge.
  • Mobile Support: Implement touch controls for mobile devices.

This simple maze game is a fun and educational project to practice JavaScript and canvas drawing. Happy coding! 🎮

Comments are closed.