原生js实现走出迷宫小游戏代码

代码语言:html

所属分类:背景

代码描述:原生js实现走出迷宫小游戏代码,用键盘上下左右键操作移动笑脸走出迷宫到达出口房子就算胜利。

代码标签: js 走出 迷宫 游戏

下面为部分代码预览,完整代码请点击下载或在bfwstudio webide中打开


<!DOCTYPE html>
<html lang="en" >

<head>

  <meta charset="UTF-8">
  

  <meta name="viewport" content="width=device-width, initial-scale=1">
  
  
  
<style>
body {
	touch-action: pan-y;
}
#container {
	position: absolute;
	top: 0;
	left: 0;
	right: 0;
	bottom: 0;
	background: #222;
	display: grid;
	grid-template-rows: 60% 40%;
}

#maze {
	position: absolute;
	width: 340px;
	height: 240px;
	/*background: #39a;
	
	align-self: center;
	justify-self: center;
	place-self: center center;*/
	top: 30vh;
	left: 50%;
	transform: translate(-50%, -50%);
}

.mbox,
.controls {
	height: 100%;
	background: #222;
	display: grid;
}

.mbox {
}

.buttons {
	width: 210px;
	height: 140px;
	background: #222;
	align-self: center;
	justify-self: center;
	display: grid;
	grid-template-rows: 70px 70px;
	grid-template-columns: 70px 70px 70px;
}

.btn {
	width: 60px;
	height: 60px;
	border: 2px #fff solid;
	border-bottom: 2px #fff solid;
	align-self: center;
	justify-self: center;
	cursor: pointer;
	border-radius: 8px;
	display: grid;
	/*box-shadow: 4px 4px 10px rgba(255, 255, 255, 0.2);*/
}
.chevron {
	height: 20px;
	width: 20px;
	align-self: center;
	justify-self: center;
	color: #222;
	font-size: 20px;
	line-height: 20px;
	text-align: center;
	color: #fff;
}

#bu {
	grid-column-start: 2;
}
#bd {
	grid-column-start: 2;
	grid-row-start: 2;
}
#bl {
	grid-column-start: 1;
	grid-row-start: 2;
}
#br {
	grid-column-start: 3;
	grid-row-start: 2;
}

#thingie,
#home {
	position: absolute;
	top: 100px;
	left: 100px;
	width: 20px;
	height: 20px;
	border-radius: 20px;
	/*background: #39a;
	transition: all .1s;*/
}

.emo {
	position: absolute;
	top: 4px;
	left: 1px;
	width: 13px;
	height: 13px;
	border-radius: 20px;
	font-size: 15px;
	line-height: 15px;
	text-align: left;
}

.barrier {
	position: absolute;
	background: #fff;
}

#top {
	top: 20px;
	left: 20px;
	width: 300px;
	height: 2px;
}

#bottom {
	top: 220px;
	left: 20px;
	width: 302px;
	height: 2px;
}

/*style reset*/
button {
	display: inline-block;
	border: none;
	padding: none;
	margin: 0;
	outline: none;
	-webkit-appearance: none;
	-moz-appearance: none;
	background: none;
	-webkit-tap-highlight-color: transparent;
}

button:hover,
button:focus {
	-webkit-appearance: none;
}

button:focus {
	outline: none;
}

button:active {
	transform: scale(1);
	-webkit-appearance: none;
}
</style>



</head>

<body >
 
<div id="container">
	<div class="mbox">
	<div id="maze">
		<div id="thingie">
			<div class="emo" id="emo">🥺</div>
		</div>
		<div id="home">
			<div class="emo">🏠</div>
		</div>
		<div class="barrier" id="top"></div>
		<div class="barrier" id="bottom"></div>
	</div>
		</div>
	<div class="controls">
		<div class="buttons">
			<button class="btn" id="bu"><div class="chevron">↑</div></button>
			<button class="btn" id="bd"><div class="chevron">↓</div></button>
			<button class="btn" id="bl"><div class="chevron">←</div></button>
			<button class="btn" id="br"><div class="chevron">→</div></button>
		</div>
	</div>
</div>

  
      <script>
const cont = document.getElementById("container");
const maze = document.getElementById("maze");
const thingie = document.getElementById("thingie");
const home = document.getElementById("home");
const emo = document.getElementById("emo");

const bu = document.getElementById("bu");
const bd = document.getElementById("bd");
const bl = document.getElementById("bl");
const br = document.getElementById("br");

const step = 20;
const size = 20;
const bwidth = 2;
const mazeHeight = 200;
const mazeWidth = 300;
let nogoX = [];
let nogoX2 = [];
let nogoY = [];
let nogoY2 = [];
let prevDist = mazeWidth * 2;

//tilt vars
let lastUD = 0;
let lastLR = 0;
const mThreshold = 15;
let firstMove = true;
let allowTilt = true;

//swipe vars
const sThreshold = 15;

//scroll vars
const scThreshold = 20;

//generate sides and starting position
genSides();

//define size
let my = mazeHeight / step;
let mx = mazeWidth / step;

//create full grid
let grid = [];
for (let i = 0; i < my; i++) {
  let sg = [];
  for (let a = 0; a < mx; a++) {
    sg.push({ u: 0, d: 0, l: 0, r: 0, v: 0 });
  }
  grid.push(sg);
}

//create direction arrays
let dirs = ["u", "d", "l", "r"];
let modDir = {
  u: { y: -1, x: 0, o: "d" },
  d: { y: 1, x: 0, o: "u" },
  l: { y: 0, x: -1, o: "r" },
  r: { y: 0, x: 1, o: "l" } };


//generate maze
genMaze(0, 0, 0);
drawMaze();

//get all the barriers
const barriers = document.getElementsByClassName("barrier");
for (let b = 0; b < barriers.length; b++) {
  nogoX.push(barriers[b].offsetLeft);
  nogoX2.push(barriers[b].offsetLeft + barriers[b].clientWidth);
  nogoY.push(barriers[b].offsetTop);
  nogoY2.push(barriers[b].offsetTop + barriers[b].clientHeight);
}
//console.log(nogoX, nogoX2, nogoY, nogoY2);

document.addEventListener("keydown", keys);

function keys(e) {
  let code = e.code;
  switch (code) {
    //arrows
    case "ArrowUp":
      up();
      break;
    case "ArrowDown":
      down();
      break;
    case "ArrowLeft":
      left();
      break;
    case "ArrowRight":
      right();
      break;
    //wasd
    case "KeyW":
      up();
      break;
    case "KeyS":
      down();
      break;
    case "KeyA":
      left();
      break;
    case "KeyD":
      right();
      break;}

}

bu.addEventListener("click", e => {
  up();
  firstMove = true;
});
bd.addEventListener("click", e => {
  down();
  firstMove = true;
});
bl.addEventListener("click", e => {
  left();
  firstMove = true;
});
br.addEventListener("click", e => {
  right();
  firstMove = true;
});

function up() {
  animKeys(bu);
  if (checkYboundry("u")) {
    thingie.style.top = thingie.offsetTop - step + "px";
    updateEmo(false);
  }
}

function down() {
  animKeys(bd);
  if (checkYboundry("d")) {
    thingie.style.top = thingie.offsetTop + step + "px";
    updateEmo(false);
  }
}

function left() {
  animKeys(bl);
  if (checkXboundry("l")) {
    thingie.style.left = thingie.offsetLeft - step + "px";
  }
  updateEmo(true);
}

function right() {
  animKeys(br);
  if (checkXboundry("r")) {
    thingie.style.left = thingie.offsetLeft + step + "px";
  }
  updateEmo(true);
}

//check if one can move horizontally
function checkXboundry(dir) {
  let x = thingie.offsetLeft;
  let y = thingie.offsetTop;
  let ok = [];
  let len = Math.max(nogoX.length, nogoX2.length, nogoY.length, nogoY2.length);

  let check = 0;
  for (let i = 0; i < len; i++) {
    check = 0;
    if (y < nogoY[i] || y > nogoY2[i] - size) {
      check = 1;
    }
    if (dir === "r") {
      if (x < nogoX[i] - size || x > nogoX2[i] - size) {
        check = 1;
      }
    }
    if (dir === "l") {
      if (x < nogoX[i] || x > nogoX2[i]) {
        check = 1;
      }
    }
    ok.push(check);
  }
  //check what to return
  let res = ok.every(function (e) {
    return e > 0;
  });
  return res;
}

//check if one can move vertically
function checkYboundry(dir) {
  let x = thingie.offsetLeft;
  let y = thingie.offsetTop;
  let ok = [];
  let len = Math.max(nogoX.length, nogoX2.length, nogoY.length, nogoY2.length);

  let check = 0;
  for (let i = 0; i < len; i++) {
    check = 0;
    if (x < nogoX[i] || x > nogoX2[i] - size) {
      check = 1;
    }
    if (dir === "u") {
      if (y < nogoY[i] || y > nogoY2[i]) {
        check = 1;
      }
    }
    if (dir === "d") {
      if (y < nogoY[i] - size || y > nogoY2[i] - size) {
        check = 1;
      }
    }
    ok.push(check);
  }
  //check what to return
  let res = ok.every(function (e) {
    return e > 0;
  });
  return res;
}

//generate sides with random entry and exit points
function genSides() {
  let max = mazeHeight / step;
  let l1 = Math.floor(Math.random() * max) * step;
  //let l1 = 0;
  let l2 = mazeHeight - step - l1;
  //console.log(l1, l2);

  let lb1 = document.createElement("div");
  lb1.style.top = step + "px";
  lb1.style.left = step + "px";
  lb1.style.height = l1 + "px";

  let lb2 = document.createElement("div");
  lb2.style.top = l1 + step * 2 + "px";
  lb2.style.left = step + "px";
  lb2.style.height = l2 + "px";

  let rb1 = document.createElement("div");
  rb1.style.top = step + "px";
  rb1.style.left = mazeWidth + step + "px";
  rb1.style.height = l2 + "px";

  let rb2 = document.createElement("div");
  rb2.style.top = l2 + step * 2 + "px";
  rb2.style.left = mazeWidth + step + "px";
  rb2.style.height = l1 + "px";

  //create invisible barriers for start and end: vertical left, vertical right, left top, left bottom, right top, right bottom
  nogoX.push(0, mazeWidth + 2 * step, 0, 0, mazeWidth + step, mazeWidth + step);
  nogoX2.push(
  0 + bwidth,
  mazeWidth + 2 * step + bwidth,
  step,
  step,
  mazeWidth + 2 * step,
  mazeWidth + 2 * step);

  nogoY.push(
  l1 + step,
  l2 + step,
  l1 + step,
  l1 + 2 * step,
  l2 + step,
  l2 + 2 * step);

  nogoY2.push(
  l1 + 2 * step,
  l2 + 2 * step,
  l1 + step + bwidth,
  l1 + 2 * step + bwidth,
  l2 + step + bwidth,
  l2 + 2 * step + bwidth);

  //set start-pos
  thingie.style.top = l1 + step + "px";
  thingie.style.left = 0 + "px";
  //set end-pos & store height of end
  home.style.top = l2 + step + "px";
  home.style.left = mazeWidth + step + "px";

  //style & append
  let els = [lb1, lb2, rb1, rb2];
  for (let i = 0; i < els.length; i++) {
    confSideEl(els[i]);
    maze.appendChild(els[i]);
  }
}

function confSideEl(el) {
  el.setAttribute("class", "barrier");
  el.style.width = bwidth + "px";
}

//gen maze using Recursive Backtracking
function genMaze(cx, cy, s) {
  // shuffle unchecked directions
  let d = limShuffle(dirs, s);

  for (let i = 0; i < d.length; i++) {
    let nx = cx + modDir[d[i]].x;
    let ny = cy + modDir[d[i]].y;
    grid[cy][cx].v = 1;

    if (nx >= 0 && nx < mx && ny >= 0 && ny < my && grid[ny][nx].v === 0) {
      grid[cy][cx][d[i]] = 1;
      grid[ny][nx][modDir[d[i]].o] = 1;
      //avoid shuffling d if d's not exhausted.. hence the i
      genMaze(nx, ny, i);
    }
  }
}

//draw maze
function drawMaze() {
  for (let x = 0; x < mx; x++) {
    for (let y = 0; y < my; y++) {
      let l .........完整代码请登录后点击上方下载按钮下载查看

网友评论0