Maze Game using HTML CSS JavaScript With Source Code

maze game using html css js

Introduction :

The Maze Game is a fun Maze Game using HTML CSS JavaScript, interactive browser-based game developed using HTML, CSS, and JavaScript. The objective of the game is to navigate a player through a maze from the starting point to the finish line. This project demonstrates the use of front-end technologies to create a dynamic and engaging game that runs directly in the browser without the need for any plugins or additional software.

Tech Stack

  • HTML5: Provides the basic structure of the game.
  • CSS3: Used to style the maze, player, and other game elements.
  • JavaScript: Implements the game logic, including player movement, collision detection, and win conditions.

Features of the Maze Game

  1. Interactive Gameplay:
    The player can navigate through the maze using keyboard controls, providing an engaging and interactive experience.

  2. Responsive Design:
    The game is designed to be responsive, adapting to different screen sizes and devices, including desktops, laptops, and tablets.

  3. Simple and Clean Interface:
    The interface is minimalistic and user-friendly, with clear paths and intuitive controls.

  4. Collision Detection:
    JavaScript is used to detect collisions between the player and the maze walls, preventing movement through walls.

  5. Win Condition:
    A winning message is displayed when the player successfully reaches the finish line.

How to Run Below Source Code:

To run the provided code, you can follow these steps:

  1. Create an HTML file: Open a text editor (like Notepad, Visual Studio Code, or Sublime Text) and copy the entire code into a new file. Save the file with a .html extension, for example, maze_game.html.

  2. Open the HTML file in a web browser: Double-click on the HTML file you created, and it should open in your default web browser. Alternatively, you can right-click on the file and choose “Open with” to select a specific browser.

  3. Play the game: Once the HTML file is opened in the browser, you should see the maze grid displayed on the screen. You can use the arrow keys on your keyboard to navigate the blue cell (representing the player) through the maze. The goal is to reach the red cell (the end of the maze). If you reach the end, an alert will pop up declaring victory.

How the Maze Game Works

1. HTML Structure

The HTML file sets up the basic structure of the game, including the game board (maze), player, and goal. The main components include:

  • Game Board: A container element (<div>) representing the maze.
  • Player: A movable element within the maze.
  • Goal: The target area the player needs to reach.

Here is a simplified example of the HTML structure:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Maze Game</title>
    <link rel="stylesheet" href="style.css">
</head>
<body>
    <div id="maze">
        <div id="player"></div>
        <div id="goal"></div>
    </div>
    <script src="script.js"></script>
</body>
</html>

2. CSS Styling

CSS is used to style the maze, the player, and other elements to create a visually appealing game environment. Key styles include:

  • Flexbox and Positioning: CSS Flexbox is used for layout, and absolute positioning is used to place elements within the maze.
  • Background Colors and Borders: Different colors and borders are used to define walls, paths, the player, and the goal.

An example of the CSS styling:

 
body {
    margin: 0;
    display: flex;
    justify-content: center;
    align-items: center;
    height: 100vh;
    background-color: #333;
}

#maze {
    width: 300px;
    height: 300px;
    position: relative;
    border: 2px solid #fff;
}

#player {
    width: 20px;
    height: 20px;
    background-color: red;
    position: absolute;
    top: 10px;
    left: 10px;
}

#goal {
    width: 20px;
    height: 20px;
    background-color: green;
    position: absolute;
    bottom: 10px;
    right: 10px;
}

3. JavaScript Logic

JavaScript is used to handle game logic, including player movement, collision detection, and the win condition.

Player Movement:

The player can move using keyboard arrow keys. Event listeners are added to listen for key presses and update the player’s position accordingly.

 
document.addEventListener('keydown', movePlayer);

function movePlayer(event) {
    const player = document.getElementById('player');
    let top = parseInt(player.style.top);
    let left = parseInt(player.style.left);

    switch (event.key) {
        case 'ArrowUp':
            top -= 10;
            break;
        case 'ArrowDown':
            top += 10;
            break;
        case 'ArrowLeft':
            left -= 10;
            break;
        case 'ArrowRight':
            left += 10;
            break;
    }

    if (canMoveTo(left, top)) {
        player.style.left = `${left}px`;
        player.style.top = `${top}px`;
    }
}

function canMoveTo(left, top) {
    // Collision detection logic to ensure the player doesn't move through walls
    return true; // Placeholder for actual collision detection
}

Collision Detection:

A basic function is used to check if the player’s new position will collide with a wall. If there is a collision, the player’s position is not updated.

Win Condition:

When the player reaches the goal position, a win message is displayed:

function checkWinCondition() {
    const player = document.getElementById('player');
    const goal = document.getElementById('goal');

    if (player.style.left === goal.style.left && player.style.top === goal.style.top) {
        alert('Congratulations! You reached the goal!');
    }
}

Source Code:

Your download is starting now...

HTML (Index.html)

				
					<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Maze Game</title>
  
  <link data-asynced="1" as="style" onload="this.onload=null;this.rel='stylesheet'"  rel="preload" href="style.css">
</head>
<body>
  
  <div id="maze-container"></div>
  <div id="controls">
    <label for="size">Maze Size:</label>
    <input type="number" id="size" value="21" min="5" max="51" step="2">
    <button id="generate">Generate Maze</button>
    <button id="solve">Show Solution</button>
  </div>
  
   <script type="litespeed/javascript" data-src="script.js"></script> <script data-no-optimize="1">!function(t,e){"object"==typeof exports&&"undefined"!=typeof module?module.exports=e():"function"==typeof define&&define.amd?define(e):(t="undefined"!=typeof globalThis?globalThis:t||self).LazyLoad=e()}(this,function(){"use strict";function e(){return(e=Object.assign||function(t){for(var e=1;e<arguments.length;e++){var n,a=arguments[e];for(n in a)Object.prototype.hasOwnProperty.call(a,n)&&(t[n]=a[n])}return t}).apply(this,arguments)}function i(t){return e({},it,t)}function o(t,e){var n,a="LazyLoad::Initialized",i=new t(e);try{n=new CustomEvent(a,{detail:{instance:i}})}catch(t){(n=document.createEvent("CustomEvent")).initCustomEvent(a,!1,!1,{instance:i})}window.dispatchEvent(n)}function l(t,e){return t.getAttribute(gt+e)}function c(t){return l(t,bt)}function s(t,e){return function(t,e,n){e=gt+e;null!==n?t.setAttribute(e,n):t.removeAttribute(e)}(t,bt,e)}function r(t){return s(t,null),0}function u(t){return null===c(t)}function d(t){return c(t)===vt}function f(t,e,n,a){t&&(void 0===a?void 0===n?t(e):t(e,n):t(e,n,a))}function _(t,e){nt?t.classList.add(e):t.className+=(t.className?" ":"")+e}function v(t,e){nt?t.classList.remove(e):t.className=t.className.replace(new RegExp("(^|\\s+)"+e+"(\\s+|$)")," ").replace(/^\s+/,"").replace(/\s+$/,"")}function g(t){return t.llTempImage}function b(t,e){!e||(e=e._observer)&&e.unobserve(t)}function p(t,e){t&&(t.loadingCount+=e)}function h(t,e){t&&(t.toLoadCount=e)}function n(t){for(var e,n=[],a=0;e=t.children[a];a+=1)"SOURCE"===e.tagName&&n.push(e);return n}function m(t,e){(t=t.parentNode)&&"PICTURE"===t.tagName&&n(t).forEach(e)}function a(t,e){n(t).forEach(e)}function E(t){return!!t[st]}function I(t){return t[st]}function y(t){return delete t[st]}function A(e,t){var n;E(e)||(n={},t.forEach(function(t){n[t]=e.getAttribute(t)}),e[st]=n)}function k(a,t){var i;E(a)&&(i=I(a),t.forEach(function(t){var e,n;e=a,(t=i[n=t])?e.setAttribute(n,t):e.removeAttribute(n)}))}function L(t,e,n){_(t,e.class_loading),s(t,ut),n&&(p(n,1),f(e.callback_loading,t,n))}function w(t,e,n){n&&t.setAttribute(e,n)}function x(t,e){w(t,ct,l(t,e.data_sizes)),w(t,rt,l(t,e.data_srcset)),w(t,ot,l(t,e.data_src))}function O(t,e,n){var a=l(t,e.data_bg_multi),i=l(t,e.data_bg_multi_hidpi);(a=at&&i?i:a)&&(t.style.backgroundImage=a,n=n,_(t=t,(e=e).class_applied),s(t,ft),n&&(e.unobserve_completed&&b(t,e),f(e.callback_applied,t,n)))}function N(t,e){!e||0<e.loadingCount||0<e.toLoadCount||f(t.callback_finish,e)}function C(t,e,n){t.addEventListener(e,n),t.llEvLisnrs[e]=n}function M(t){return!!t.llEvLisnrs}function z(t){if(M(t)){var e,n,a=t.llEvLisnrs;for(e in a){var i=a[e];n=e,i=i,t.removeEventListener(n,i)}delete t.llEvLisnrs}}function R(t,e,n){var a;delete t.llTempImage,p(n,-1),(a=n)&&--a.toLoadCount,v(t,e.class_loading),e.unobserve_completed&&b(t,n)}function T(o,r,c){var l=g(o)||o;M(l)||function(t,e,n){M(t)||(t.llEvLisnrs={});var a="VIDEO"===t.tagName?"loadeddata":"load";C(t,a,e),C(t,"error",n)}(l,function(t){var e,n,a,i;n=r,a=c,i=d(e=o),R(e,n,a),_(e,n.class_loaded),s(e,dt),f(n.callback_loaded,e,a),i||N(n,a),z(l)},function(t){var e,n,a,i;n=r,a=c,i=d(e=o),R(e,n,a),_(e,n.class_error),s(e,_t),f(n.callback_error,e,a),i||N(n,a),z(l)})}function G(t,e,n){var a,i,o,r,c;t.llTempImage=document.createElement("IMG"),T(t,e,n),E(c=t)||(c[st]={backgroundImage:c.style.backgroundImage}),o=n,r=l(a=t,(i=e).data_bg),c=l(a,i.data_bg_hidpi),(r=at&&c?c:r)&&(a.style.backgroundImage='url("'.concat(r,'")'),g(a).setAttribute(ot,r),L(a,i,o)),O(t,e,n)}function D(t,e,n){var a;T(t,e,n),a=e,e=n,(t=It[(n=t).tagName])&&(t(n,a),L(n,a,e))}function V(t,e,n){var a;a=t,(-1<yt.indexOf(a.tagName)?D:G)(t,e,n)}function F(t,e,n){var a;t.setAttribute("loading","lazy"),T(t,e,n),a=e,(e=It[(n=t).tagName])&&e(n,a),s(t,vt)}function j(t){t.removeAttribute(ot),t.removeAttribute(rt),t.removeAttribute(ct)}function P(t){m(t,function(t){k(t,Et)}),k(t,Et)}function S(t){var e;(e=At[t.tagName])?e(t):E(e=t)&&(t=I(e),e.style.backgroundImage=t.backgroundImage)}function U(t,e){var n;S(t),n=e,u(e=t)||d(e)||(v(e,n.class_entered),v(e,n.class_exited),v(e,n.class_applied),v(e,n.class_loading),v(e,n.class_loaded),v(e,n.class_error)),r(t),y(t)}function $(t,e,n,a){var i;n.cancel_on_exit&&(c(t)!==ut||"IMG"===t.tagName&&(z(t),m(i=t,function(t){j(t)}),j(i),P(t),v(t,n.class_loading),p(a,-1),r(t),f(n.callback_cancel,t,e,a)))}function q(t,e,n,a){var i,o,r=(o=t,0<=pt.indexOf(c(o)));s(t,"entered"),_(t,n.class_entered),v(t,n.class_exited),i=t,o=a,n.unobserve_entered&&b(i,o),f(n.callback_enter,t,e,a),r||V(t,n,a)}function H(t){return t.use_native&&"loading"in HTMLImageElement.prototype}function B(t,i,o){t.forEach(function(t){return(a=t).isIntersecting||0<a.intersectionRatio?q(t.target,t,i,o):(e=t.target,n=t,a=i,t=o,void(u(e)||(_(e,a.class_exited),$(e,n,a,t),f(a.callback_exit,e,n,t))));var e,n,a})}function J(e,n){var t;et&&!H(e)&&(n._observer=new IntersectionObserver(function(t){B(t,e,n)},{root:(t=e).container===document?null:t.container,rootMargin:t.thresholds||t.threshold+"px"}))}function K(t){return Array.prototype.slice.call(t)}function Q(t){return t.container.querySelectorAll(t.elements_selector)}function W(t){return c(t)===_t}function X(t,e){return e=t||Q(e),K(e).filter(u)}function Y(e,t){var n;(n=Q(e),K(n).filter(W)).forEach(function(t){v(t,e.class_error),r(t)}),t.update()}function t(t,e){var n,a,t=i(t);this._settings=t,this.loadingCount=0,J(t,this),n=t,a=this,Z&&window.addEventListener("online",function(){Y(n,a)}),this.update(e)}var Z="undefined"!=typeof window,tt=Z&&!("onscroll"in window)||"undefined"!=typeof navigator&&/(gle|ing|ro)bot|crawl|spider/i.test(navigator.userAgent),et=Z&&"IntersectionObserver"in window,nt=Z&&"classList"in document.createElement("p"),at=Z&&1<window.devicePixelRatio,it={elements_selector:".lazy",container:tt||Z?document:null,threshold:300,thresholds:null,data_src:"src",data_srcset:"srcset",data_sizes:"sizes",data_bg:"bg",data_bg_hidpi:"bg-hidpi",data_bg_multi:"bg-multi",data_bg_multi_hidpi:"bg-multi-hidpi",data_poster:"poster",class_applied:"applied",class_loading:"litespeed-loading",class_loaded:"litespeed-loaded",class_error:"error",class_entered:"entered",class_exited:"exited",unobserve_completed:!0,unobserve_entered:!1,cancel_on_exit:!0,callback_enter:null,callback_exit:null,callback_applied:null,callback_loading:null,callback_loaded:null,callback_error:null,callback_finish:null,callback_cancel:null,use_native:!1},ot="src",rt="srcset",ct="sizes",lt="poster",st="llOriginalAttrs",ut="loading",dt="loaded",ft="applied",_t="error",vt="native",gt="data-",bt="ll-status",pt=[ut,dt,ft,_t],ht=[ot],mt=[ot,lt],Et=[ot,rt,ct],It={IMG:function(t,e){m(t,function(t){A(t,Et),x(t,e)}),A(t,Et),x(t,e)},IFRAME:function(t,e){A(t,ht),w(t,ot,l(t,e.data_src))},VIDEO:function(t,e){a(t,function(t){A(t,ht),w(t,ot,l(t,e.data_src))}),A(t,mt),w(t,lt,l(t,e.data_poster)),w(t,ot,l(t,e.data_src)),t.load()}},yt=["IMG","IFRAME","VIDEO"],At={IMG:P,IFRAME:function(t){k(t,ht)},VIDEO:function(t){a(t,function(t){k(t,ht)}),k(t,mt),t.load()}},kt=["IMG","IFRAME","VIDEO"];return t.prototype={update:function(t){var e,n,a,i=this._settings,o=X(t,i);{if(h(this,o.length),!tt&&et)return H(i)?(e=i,n=this,o.forEach(function(t){-1!==kt.indexOf(t.tagName)&&F(t,e,n)}),void h(n,0)):(t=this._observer,i=o,t.disconnect(),a=t,void i.forEach(function(t){a.observe(t)}));this.loadAll(o)}},destroy:function(){this._observer&&this._observer.disconnect(),Q(this._settings).forEach(function(t){y(t)}),delete this._observer,delete this._settings,delete this.loadingCount,delete this.toLoadCount},loadAll:function(t){var e=this,n=this._settings;X(t,n).forEach(function(t){b(t,e),V(t,n,e)})},restoreAll:function(){var e=this._settings;Q(e).forEach(function(t){U(t,e)})}},t.load=function(t,e){e=i(e);V(t,e)},t.resetStatus=function(t){r(t)},Z&&function(t,e){if(e)if(e.length)for(var n,a=0;n=e[a];a+=1)o(t,n);else o(t,e)}(t,window.lazyLoadOptions),t});!function(e,t){"use strict";function a(){t.body.classList.add("litespeed_lazyloaded")}function n(){console.log("[LiteSpeed] Start Lazy Load Images"),d=new LazyLoad({elements_selector:"[data-lazyloaded]",callback_finish:a}),o=function(){d.update()},e.MutationObserver&&new MutationObserver(o).observe(t.documentElement,{childList:!0,subtree:!0,attributes:!0})}var d,o;e.addEventListener?e.addEventListener("load",n,!1):e.attachEvent("onload",n)}(window,document);</script><script data-no-optimize="1">var litespeed_vary=document.cookie.replace(/(?:(?:^|.*;\s*)_lscache_vary\s*\=\s*([^;]*).*$)|^.*$/,"");litespeed_vary||fetch("/wp-content/plugins/litespeed-cache/guest.vary.php",{method:"POST",cache:"no-cache",redirect:"follow"}).then(e=>e.json()).then(e=>{console.log(e),e.hasOwnProperty("reload")&&"yes"==e.reload&&(sessionStorage.setItem("litespeed_docref",document.referrer),window.location.reload(!0))});</script><script data-optimized="1" type="litespeed/javascript" data-src="https://codewithcurious.com/wp-content/litespeed/js/498f68a5eb4ec694db8478345e6b6a23.js?ver=971c1"></script><script>const litespeed_ui_events=["mouseover","click","keydown","wheel","touchmove","touchstart"];var urlCreator=window.URL||window.webkitURL;function litespeed_load_delayed_js_force(){console.log("[LiteSpeed] Start Load JS Delayed"),litespeed_ui_events.forEach(e=>{window.removeEventListener(e,litespeed_load_delayed_js_force,{passive:!0})}),document.querySelectorAll("iframe[data-litespeed-src]").forEach(e=>{e.setAttribute("src",e.getAttribute("data-litespeed-src"))}),"loading"==document.readyState?window.addEventListener("DOMContentLoaded",litespeed_load_delayed_js):litespeed_load_delayed_js()}litespeed_ui_events.forEach(e=>{window.addEventListener(e,litespeed_load_delayed_js_force,{passive:!0})});async function litespeed_load_delayed_js(){let t=[];for(var d in document.querySelectorAll('script[type="litespeed/javascript"]').forEach(e=>{t.push(e)}),t)await new Promise(e=>litespeed_load_one(t[d],e));document.dispatchEvent(new Event("DOMContentLiteSpeedLoaded")),window.dispatchEvent(new Event("DOMContentLiteSpeedLoaded"))}function litespeed_load_one(t,e){console.log("[LiteSpeed] Load ",t);var d=document.createElement("script");d.addEventListener("load",e),d.addEventListener("error",e),t.getAttributeNames().forEach(e=>{"type"!=e&&d.setAttribute("data-src"==e?"src":e,t.getAttribute(e))});let a=!(d.type="text/javascript");!d.src&&t.textContent&&(d.src=litespeed_inline2src(t.textContent),a=!0),t.after(d),t.remove(),a&&e()}function litespeed_inline2src(t){try{var d=urlCreator.createObjectURL(new Blob([t.replace(/^(?:<!--)?(.*?)(?:-->)?$/gm,"$1")],{type:"text/javascript"}))}catch(e){d="data:text/javascript;base64,"+btoa(t.replace(/^(?:<!--)?(.*?)(?:-->)?$/gm,"$1"))}return d}</script></body>
</html>

				
			

CSS (Style.css)

				
					body {
  display: flex;
  flex-direction: column;
  align-items: center;
  height: 100vh;
  margin: 70px;
  background-color: #d8f3dc;
  overflow: hidden;
}
:root {
  --border-color: #38a3a5;
  --border-size: 1px;
  --border-wh: 100%;
  --cell-size: 20px;
}
button {
  background: #38a3a5;
  border: 2px solid #57cc99;
  color: #d8f3dc;
  padding: 5px;
  font-size: large;
}
input#size {
  border: 1px solid #57cc99;
  padding: 5px;
  background: #ffffff;
  color: #38a3a5;
}
label {
  color: #38a3a5;
}
.cell.start {
  background-color: green;
}

.cell.end {
  background-color: red;
}

.cell.player {
  background: radial-gradient(circle at center, black 0.25rem, transparent 0);
}

.cell.solution {
  background-color: #57cc99;
}

#controls {
  margin: 20px;
}

#maze-container {
  display: grid;
  gap: 0;
  border: var(--border-color) 11px solid;
}

.cell {
  position: relative;
  width: var(--cell-size);
  height: var(--cell-size);
  background-color: white;
}

.cell::before,
.cell::after {
  content: "";
  position: absolute;
  background-color: var(--border-color);
  z-index: 1;
}

.cell.top::before {
  width: var(--border-wh);
  height: var(--border-size);
  /* top: -10px;
  left: -10px; */
  top: 0;
  left: 0;
}

.cell.right::after {
  width: var(--border-size);
  height: var(--border-wh);
  top: 0px;
  right: 0px;
}

span {
  font-size: xx-small;
}
span.right-hand::before {
  content: "";
  display: block;
  background: black;
  width: 50%;
  height: 2px;
  position: absolute;
  top: 50%;
  left: 0;
  transform: translate(0%, -50%);
}
span.left-hand::before {
  content: "";
  display: block;
  background: black;
  width: 50%;
  height: 2px;
  position: absolute;
  top: 50%;
  right: 0;
  transform: translate(0%, -50%);
}
span.bottom-hand::before {
  content: "";
  display: block;
  background: black;
  width: 2px;
  height: 50%;
  position: absolute;
  top: 0;
  left: 50%;
  transform: translate(-50%, 0%);
}
span.top-hand::before {
  content: "";
  display: block;
  background: black;
  width: 2px;
  height: 50%;
  position: absolute;
  bottom: 0;
  left: 50%;
  transform: translate(-50%, 0%);
}

span.to-left::after {
  content: "";
  display: block;
  background: black;
  width: 50%;
  height: 2px;
  position: absolute;
  top: 50%;
  left: 0;
  transform: translate(0%, -50%);
}
span.to-right::after {
  content: "";
  display: block;
  background: black;
  width: 50%;
  height: 2px;
  position: absolute;
  top: 50%;
  right: 0;
  transform: translate(0%, -50%);
}
span.to-top::after {
  content: "";
  display: block;
  background: black;
  width: 2px;
  height: 50%;
  position: absolute;
  top: 0;
  left: 50%;
  transform: translate(-50%, 0%);
}
span.to-bottom::after {
  content: "";
  display: block;
  background: black;
  width: 2px;
  height: 50%;
  position: absolute;
  bottom: 0;
  left: 50%;
  transform: translate(-50%, 0%);
}

#controls2 {
  position: absolute;
  top: 50%;
  left: 100px;
  transform: translate(-50%, -50%);
}

				
			

Javascript(Script.js)

				
					let mazeContainer = document.getElementById("maze-container");
let sizeInput = document.getElementById("size");
let generateButton = document.getElementById("generate");
let solveButton = document.getElementById("solve");

let size = parseInt(sizeInput.value);
let maze = generateMaze(size);
let playerPosition = { x: 0, y: 0 };
let previousPosition = { x: 0, y: 0 };
let visited = {};
let previousPositions = [];
let PlayerCanMove = true;

renderMaze(maze);

generateButton.addEventListener("click", () => {
  size = parseInt(sizeInput.value);
  maze = generateMaze(size);
  playerPosition = { x: 0, y: 0 };
  visited = {};
  PlayerCanMove = true;

  renderMaze(maze);
});

solveButton.addEventListener("click", () => {
  PlayerCanMove = false;
  const solution = solveMaze(maze, size);
  animateSolution(solution);
});

document.addEventListener("keydown", movePlayer);

function generateMaze(size) {
  const maze = Array.from({ length: size }, () => Array(size).fill(15));
  const visited = Array.from({ length: size }, () => Array(size).fill(false));
  const walls = [];

  function addWalls(x, y) {
    if (x > 0 && !visited[y][x - 1]) walls.push({ x, y, direction: "left" });
    if (x < size - 1 && !visited[y][x + 1])
      walls.push({ x, y, direction: "right" });
    if (y > 0 && !visited[y - 1][x]) walls.push({ x, y, direction: "up" });
    if (y < size - 1 && !visited[y + 1][x])
      walls.push({ x, y, direction: "down" });
  }

  let x = Math.floor(Math.random() * size);
  let y = Math.floor(Math.random() * size);
  visited[y][x] = true;
  addWalls(x, y);

  while (walls.length > 0) {
    const { x, y, direction } = walls.splice(
      Math.floor(Math.random() * walls.length),
      1
    )[0];

    let nx = x,
      ny = y;
    if (direction === "left") nx--;
    if (direction === "right") nx++;
    if (direction === "up") ny--;
    if (direction === "down") ny++;

    if (nx >= 0 && ny >= 0 && nx < size && ny < size && !visited[ny][nx]) {
      visited[ny][nx] = true;

      if (direction === "left") {
        maze[y][x] &= ~1;
        maze[ny][nx] &= ~4;
      } else if (direction === "right") {
        maze[y][x] &= ~4;
        maze[ny][nx] &= ~1;
      } else if (direction === "up") {
        maze[y][x] &= ~2;
        maze[ny][nx] &= ~8;
      } else if (direction === "down") {
        maze[y][x] &= ~8;
        maze[ny][nx] &= ~2;
      }

      addWalls(nx, ny);
    }
  }

  return maze;
}

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

function renderMaze(maze, solution = []) {
  mazeContainer.style.gridTemplateColumns = `repeat(${size}, var(--cell-size))`;
  mazeContainer.style.gridTemplateRows = `repeat(${size}, var(--cell-size))`;
  mazeContainer.innerHTML = "";

  for (let y = 0; y < size; y++) {
    for (let x = 0; x < size; x++) {
      const cell = document.createElement("div");
      cell.className = "cell";
      cell.dataset.x = x;
      cell.dataset.y = y;
      if (x === 0 && y === 0) cell.classList.add("start");
      if (x === size - 1 && y === size - 1) cell.classList.add("end");
      if (solution.some((pos) => pos.x === x && pos.y === y)) {
        cell.classList.add("solution");
      }

      addWalls(cell, maze[y][x]);
      mazeContainer.appendChild(cell);
    }
  }

  const playerCell = document.querySelector(
    `.cell[data-x="${playerPosition.x}"][data-y="${playerPosition.y}"]`
  );
  playerCell.classList.add("player");
}

function addWalls(cell, value) {
  if (value & 1) cell.classList.add("left");
  if (value & 2) cell.classList.add("top");
  if (value & 4) cell.classList.add("right");
  if (value & 8) cell.classList.add("bottom");
}

function solveMaze(maze, size) {
  const directions = [
    { x: 1, y: 0 },
    { x: -1, y: 0 },
    { x: 0, y: 1 },
    { x: 0, y: -1 }
  ];
  const start = { x: 0, y: 0 };
  const end = { x: size - 1, y: size - 1 };
  const queue = [[start]];
  const visited = Array.from({ length: size }, () => Array(size).fill(false));
  visited[0][0] = true;

  while (queue.length) {
    const path = queue.shift();
    const { x, y } = path[path.length - 1];

    if (x === end.x && y === end.y) {
      return path;
    }

    for (const { x: dx, y: dy } of directions) {
      const nx = x + dx;
      const ny = y + dy;

      if (
        nx >= 0 &&
        ny >= 0 &&
        nx < size &&
        ny < size &&
        !visited[ny][nx] &&
        canMove(maze[y][x], dx, dy)
      ) {
        visited[ny][nx] = true;
        queue.push([...path, { x: nx, y: ny }]);
      }
    }
  }
  return [];
}

function canMove(cellValue, dx, dy) {
  if (dx === 1 && !(cellValue & 4)) return true;
  if (dx === -1 && !(cellValue & 1)) return true;
  if (dy === 1 && !(cellValue & 8)) return true;
  if (dy === -1 && !(cellValue & 2)) return true;
  return false;
}

function animateSolution(solution) {
  let index = 0;

  const interval = setInterval(() => {
    if (index >= solution.length) {
      clearInterval(interval);
      return;
    }

    const { x, y } = solution[index];
    const cell = document.querySelector(`.cell[data-x="${x}"][data-y="${y}"]`);
    cell.classList.add("solution");
    index++;
  }, 100);
}

function movePlayer(event) {
  const directionMap = {
    ArrowUp: { dx: 0, dy: -1 },
    ArrowDown: { dx: 0, dy: 1 },
    ArrowLeft: { dx: -1, dy: 0 },
    ArrowRight: { dx: 1, dy: 0 }
  };

  if (PlayerCanMove) {
    if (directionMap[event.key]) {
      const { dx, dy } = directionMap[event.key];
      const newX = playerPosition.x + dx;
      const newY = playerPosition.y + dy;

      if (
        newX >= 0 &&
        newY >= 0 &&
        newX < size &&
        newY < size &&
        canMove(maze[playerPosition.y][playerPosition.x], dx, dy)
      ) {
        previousPosition = { ...playerPosition };
        playerPosition.x = newX;
        playerPosition.y = newY;
        updatePlayerPosition(dx, dy);
      }
    }
  }
}

function updatePlayerPosition(dx, dy) {
  const oldCell = document.querySelector(
    `.cell[data-x="${previousPosition.x}"][data-y="${previousPosition.y}"]`
  );
  const newCell = document.querySelector(
    `.cell[data-x="${playerPosition.x}"][data-y="${playerPosition.y}"]`
  );

  oldCell.classList.remove("player");
  newCell.classList.add("player");

  let oldSpan = oldCell.querySelector("span");
  let newSpan = newCell.querySelector("span");

  if (!oldSpan) {
    oldSpan = document.createElement("span");
    oldCell.appendChild(oldSpan);
  }
  if (!newSpan) {
    newSpan = document.createElement("span");
    newCell.appendChild(newSpan);
  }

  // Oyuncu geri giderse class güncelleme
  if (
    previousPositions.length > 0 &&
    previousPositions[previousPositions.length - 1].x === playerPosition.x &&
    previousPositions[previousPositions.length - 1].y === playerPosition.y
  ) {
    previousPositions.pop();
    if (oldSpan) {
      oldSpan.className = "";
    }

    if (dx === 1) {
      newSpan.classList.remove("to-left");
    } else if (dx === -1) {
      newSpan.classList.remove("to-right");
    } else if (dy === 1) {
      newSpan.classList.remove("to-top");
    } else if (dy === -1) {
      newSpan.classList.remove("to-bottom");
    }
  } else {
    if (dx === 1) {
      oldSpan.classList.add("to-right");
      newSpan.classList.add("right-hand");
    } else if (dx === -1) {
      oldSpan.classList.add("to-left");
      newSpan.classList.add("left-hand");
    } else if (dy === 1) {
      oldSpan.classList.add("to-bottom");
      newSpan.classList.add("bottom-hand");
    } else if (dy === -1) {
      oldSpan.classList.add("to-top");
      newSpan.classList.add("top-hand");
    }
    previousPositions.push({ ...previousPosition });
  }
}

				
			

Output :

See the Pen HMTL Maze Game by Abdullah-Yilmazer (@Abdullah-Yilmazer) on CodePen.

maze game using html css javascript
maze game using html css javascript

Find More Projects

Build a Quiz Game Using HTML CSS and JavaScript Introduction Hello coders, you might have played various games, but were you aware …

Emoji Catcher Game Using HTML CSS and JavaScript Introduction Hello Coders, Welcome to another new blog. In this article we’ve made a …

Typing Challenge Using HTML CSS and JavaScript Introduction Hello friends, all you developer friends are welcome to our new project. If you …

Breakout Game Using HTML CSS and JavaScript With Source Code Introduction Hello friends, welcome to today’s new blog post. All of you …

Digital and Analog Clock using HTML CSS and JavaScript Introduction : This project is a digital clock and stopwatch system, which allows …

Coffee Shop Website using HTML, CSS & JavaScript Introduction : This project is a website for coffee house business. It uses HTML …

More HTML CSS JS Projects
Get Huge Discounts

All Coding Handwritten Notes