迷宫游戏 [英] Maze game in js

查看:90
本文介绍了迷宫游戏的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

试图创建一个迷宫游戏,我先遇到麻烦,首先要使箭头键连接起来,然后两个试图弄清楚如何找到玩家所在的位置,并确保他们不能穿过墙壁

Trying to create a maze game and im having trouble first getting the arrow keys to connect and two trying to figure out how to find where the player is and make sure they arent able to go through walls

const map = [
  "WWWWWWWWWWWWWWWWWWWWW",
  "W   W     W     W W W",
  "W W W WWW WWWWW W W W",
  "W W W   W     W W   W",
  "W WWWWWWW W WWW W W W",
  "W         W     W W W",
  "W WWW WWWWW WWWWW W W",
  "W W   W   W W     W W",
  "W WWWWW W W W WWW W F",
  "S     W W W W W W WWW",
  "WWWWW W W W W W W W W",
  "W     W W W   W W W W",
  "W WWWWWWW WWWWW W W W",
  "W       W       W   W",
  "WWWWWWWWWWWWWWWWWWWWW",
];


const maze = document.getElementById("maze")

let rowIndex;
let colIndex;

for (let rowNum = 0; rowNum < map.length; rowNum++) {
  const rowString = map[rowNum]
  let blockDiv = ""
  // Loops through each column
  for (let colNum = 0; colNum < rowString.length; colNum++) {
    const blockType = rowString[colNum]
    if (blockType === "W") {
      blockDiv += "<div class='block wall'></div>"
    } else if (blockType === "S") {
      blockDiv += "<div class='block start'></div>"
      rowIndex = rowNum
      colIndex = colNum
    } else if (blockType === "F") {
      blockDiv += "<div class='block finish'></div>"
    } else {
      blockDiv += "<div class='block'></div>"
    }
  };

  maze.innerHTML += `<div class='row'>${blockDiv}</div>`
}

推荐答案

这是一个很棒的项目!下面是我将如何做的简化版本.我试图根据需要添加尽可能多的评论.尝试理解它,如果有不清楚的地方,或者您想要其他地方,请不要犹豫.

That's a cool project you have here! Below is a simplified version of how I would do it. I tried to add as many comments as needed. Try to understand it, and if there is something unclear, or something else you would like, don't hesitate.

您可以单击代码下方的蓝色按钮来尝试演示:

You can click on the blue button under the code to try the demo:

const map = [
    "WWWWWWWWWWWWWWWWWWWWW",
    "W   W     W     W W W",
    "W W W WWW WWWWW W W W",
    "W W W   W     W W   W",
    "W WWWWWWW W WWW W W W",
    "W         W     W W W",
    "W WWW WWWWW WWWWW W W",
    "W W   W   W W     W W",
    "W WWWWW W W W WWW W F",
    "S     W W W W W W WWW",
    "WWWWW W W W W W W W W",
    "W     W W W   W W W W",
    "W WWWWWWW WWWWW W W W",
    "W       W       W   W",
    "WWWWWWWWWWWWWWWWWWWWW",
  ],
  maze = document.getElementById("maze"),
  restartBtn = document.getElementById('restart-btn'),
  blockSize = 10;
  
// Just for the demo, since we're in an iframe
// we display a warning to focus the window, and hide it on click
document.getElementById('warning')
        .addEventListener('click', function(){ this.style.display = 'none'; });

// We declare those variables here so that they are accessible
// from anywhere. We will assign them values in the "startGame" function
let playerPos, playerElem, finishPos;
// We'll use this in the "bumpIntoWall" function
let wallBumpTimer;

// Listen for arrow keys, and reset button click
setupEventListeners();
startGame();

function startGame() {
  const classMap = {'W': 'wall', 'S': 'start', 'F': 'finish'};
  // Empty the maze in case we already played before
  maze.innerHTML = '';
  // Create the player element
  playerElem = document.createElement('div');
  playerElem.className = 'player';
  maze.appendChild(playerElem);
  // For each row
  map.forEach((rowString, y) => {
    const row = document.createElement('div');
    row.className = 'row';
    maze.appendChild(row);
    // For each cell
    rowString.split('').forEach((blockType, x) => {
      const block = document.createElement('div');
      block.className = `block ${classMap[blockType] || ''}`;
      row.appendChild(block);
      // Set the player and finish positions as we encounter them
      if (blockType === 'S') { setPlayerPos(x, y); }
      else if (blockType === 'F') { finishPos = { x, y }; }
    });
  });
}

function setupEventListeners() {
  // When a key is pressed
  addEventListener('keydown', e => {
    const { x, y } = playerPos;
    // Try to move in the direction of the arrow
    switch(e.keyCode) {
      case 37: moveTo(x - 1, y    ); break; // Left
      case 38: moveTo(x,     y - 1); break; // Up
      case 39: moveTo(x + 1, y    ); break; // Right
      case 40: moveTo(x,     y + 1); break; // Down
    }
    // Prevent scrolling if an arrow key is pressed
    if ([37, 38, 39, 40].includes(e.keyCode)) {
      e.preventDefault();
    }
  });
  // When we click on restart, restart
  restartBtn.addEventListener('click', startGame);
}

function setPlayerPos(x, y) {
  // Update the variable
  playerPos = { x, y };
  // Update the screen
  playerElem.style.left = x * blockSize + 'px';
  playerElem.style.top = y * blockSize + 'px';
  // Display an alert if we won
  checkIfWin();
}

function checkIfWin() {
  // If the player is on the finish position
  if (playerPos.x === finishPos.x && playerPos.y === finishPos.y) {
    // Wait a little for the position to be updated visually, with setTimeout
    setTimeout(() => {
      alert("Congratulations! You made it :)");
    }, 200);
  }
}

function getBlockByPosition(x, y) {
  // Returns the corresponding HTML block
  return document.querySelector(`.row:nth-child(${y+1}) .block:nth-child(${x+1})`);
}

function getBlockTypeByPosition(x, y) {
  // Returns the block's letter ("W", "S", ...)
  return map[y].charAt(x);
}

function moveTo(x, y) {
  // Check if we are within the maze and not on a wall
  const isMoveAllowed = (
    x >= 0 && x < map[0].length &&
    y >= 0 && y < map.length    &&
    getBlockTypeByPosition(x, y) !== 'W'
  );
  if (isMoveAllowed) { setPlayerPos(x, y); }
  else { bumpIntoWall(x, y); }
}

function bumpIntoWall(nextX, nextY) {
  const { x, y } = playerPos;
  // Find out which direction the player wanted to go towards
  const direction = (nextX < x && 'left') ||
                    (nextY < y && 'up')   ||
                    (nextX > x && 'right')||
                    'down';
  clearBumpAnimation();
  // Add a class temporarily to play an animation
  playerElem.classList.add(`bump-${direction}`);
  maze.classList.add('red');
  wallBumpTimer = setTimeout(clearBumpAnimation, 200);
}

function clearBumpAnimation() {
  clearTimeout(wallBumpTimer);
  playerElem.classList.remove('bump-left', 'bump-up', 'bump-right', 'bump-down');
  maze.classList.remove('red');
}

#warning { position: fixed; background: rgba(255, 255, 255, 0.8); top: 0; left: 0; width: 100%; height: 100%; padding: 30px; text-align: center; font-size: 20px; font-family: Arial, Helvetica, sans-serif; }
#maze { position: relative; }
.row { clear: both; }
.block {
  width: 10px;
  height: 10px;
  background: #f2f2f2;
  float: left;
}
.block.wall { background: #ccc; transition: background .2s ease; }
.red .block.wall { background: #d8a2a2; }
.block.start { background: #45aed6; }
.block.finish { background: #44ffc2; }
.player {
  position: absolute;
  transition: left .2s ease, top .2s ease;
  width: 10px;
  height: 10px;
  background: #f00;
  border-radius: 10px;
}
/* Wall bump animation */
.player.bump-left { width: 8px; }
.player.bump-up { height: 8px; }
.player.bump-right { width: 8px; margin-left: 2px; }
.player.bump-down { height: 8px; margin-top: 2px; }

<button id="restart-btn">Restart</button>
<div id="maze"></div>
<div id="warning"><b>Click here</b> to focus the window,<br>and use the arrow keys to move.</div>

这篇关于迷宫游戏的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆