代码之家  ›  专栏  ›  技术社区  ›  Nike Lepz

如何在pacman游戏中检测碰撞?

  •  -2
  • Nike Lepz  · 技术社区  · 2 年前

    以下是我需要完成的Pacman游戏的样板。我在检测玩家何时会与墙壁碰撞时遇到了问题。问题是我不知道玩家相对于迷宫在哪里。就像玩家在按下键时从迷宫阵列中移动一个方块一样,我可以计算出位置并检查相邻的方块是否碰撞。但是,由于玩家在按下按键时以“1px”的增量移动,我无法跟踪它当前在哪个磁贴上。

    我尝试过的:

    我创建了两个变量来存储玩家当前的行和列。每当玩家移动时,我都会使用getBoundingClientRect()方法检查玩家是否完全在一个块内,当玩家完全在块内时,我会更新行和列跟踪器。但我遇到了一个瓶颈,因为玩家也可以在两张牌之间移动。

    请给我一些建议。

    let upPressed = false;
    let downPressed = false;
    let leftPressed = false;
    let rightPressed = false;
    
    const main = document.querySelector("main");
    
    //Player = 2, Wall = 1, Enemy = 3, Point = 0
    let maze = [
      [1, 1, 1, 1, 1, 1, 1, 1, 1, 1],
      [1, 2, 0, 1, 0, 0, 0, 0, 3, 1],
      [1, 0, 0, 0, 0, 0, 0, 1, 1, 1],
      [1, 0, 0, 0, 0, 0, 0, 0, 0, 1],
      [1, 0, 1, 1, 0, 0, 0, 0, 0, 1],
      [1, 0, 0, 0, 0, 0, 0, 1, 1, 1],
      [1, 0, 0, 1, 0, 3, 0, 0, 0, 1],
      [1, 0, 0, 0, 0, 0, 0, 1, 0, 1],
      [1, 3, 1, 0, 0, 0, 0, 0, 0, 1],
      [1, 1, 1, 1, 1, 1, 1, 1, 1, 1],
    ];
    
    //Populates the maze in the HTML
    for (let y of maze) {
      for (let x of y) {
        let block = document.createElement("div");
        block.classList.add("block");
    
        switch (x) {
          case 1:
            block.classList.add("wall");
            break;
          case 2:
            block.id = "player";
            let mouth = document.createElement("div");
            mouth.classList.add("mouth");
            block.appendChild(mouth);
            break;
          case 3:
            block.classList.add("enemy");
            break;
          default:
            block.classList.add("point");
            block.style.height = "1vh";
            block.style.width = "1vh";
        }
    
        main.appendChild(block);
      }
    }
    
    //Player movement
    
    const lbutton = document.querySelector("#lbttn");
    const rbutton = document.querySelector("#rbttn");
    const ubutton = document.querySelector("#ubttn");
    const dbutton = document.querySelector("#dbttn");
    
    function keyUp(event) {
      if (event.key === "ArrowUp") {
        upPressed = false;
        ubutton.style.borderStyle = "outset";
      } else if (event.key === "ArrowDown") {
        downPressed = false;
        dbutton.style.borderStyle = "outset";
      } else if (event.key === "ArrowLeft") {
        leftPressed = false;
        lbutton.style.borderStyle = "outset";
      } else if (event.key === "ArrowRight") {
        rightPressed = false;
        rbutton.style.borderStyle = "outset";
      }
    }
    
    function keyDown(event) {
      if (event.key === "ArrowUp") {
        upPressed = true;
        ubutton.style.borderStyle = "inset";
      } else if (event.key === "ArrowDown") {
        downPressed = true;
        dbutton.style.borderStyle = "inset";
      } else if (event.key === "ArrowLeft") {
        leftPressed = true;
        lbutton.style.borderStyle = "inset";
      } else if (event.key === "ArrowRight") {
        rightPressed = true;
        rbutton.style.borderStyle = "inset";
      }
    }
    
    const player = document.querySelector("#player");
    const playerMouth = player.querySelector(".mouth");
    let playerTop = 0;
    let playerLeft = 0;
    
    setInterval(function () {
      if (downPressed) {
        playerTop++;
        player.style.top = playerTop + "px";
        playerMouth.classList = "down";
      } else if (upPressed) {
        playerTop--;
        player.style.top = playerTop + "px";
        playerMouth.classList = "up";
      } else if (leftPressed) {
        playerLeft--;
        player.style.left = playerLeft + "px";
        playerMouth.classList = "left";
      } else if (rightPressed) {
        playerLeft++;
        player.style.left = playerLeft + "px";
        playerMouth.classList = "right";
      }
    }, 10);
    
    function startGame() {
      document.addEventListener("keydown", keyDown);
      document.addEventListener("keyup", keyUp);
      startBtn.style.display = "none";
    }
    
    const startBtn = document.querySelector(".start");
    startBtn.addEventListener("click", startGame);
    
    1 回复  |  直到 2 年前
        1
  •  1
  •   Tony    2 年前

    要检测吃豆人游戏中的碰撞,您需要跟踪玩家相对于迷宫网格的位置。以下是一种简化的方法:

    跟踪玩家位置:根据移动更新玩家的行和列。 检查碰撞:在移动之前,检查下一个位置是否是墙。 下面是一个修改后的示例:

    javascript

    let upPressed = false;
    let downPressed = false;
    let leftPressed = false;
    let rightPressed = false;
    
    const main = document.querySelector("main");
    
    //Player = 2, Wall = 1, Enemy = 3, Point = 0
    let maze = [
      [1, 1, 1, 1, 1, 1, 1, 1, 1, 1],
      [1, 2, 0, 1, 0, 0, 0, 0, 3, 1],
      [1, 0, 0, 0, 0, 0, 0, 1, 1, 1],
      [1, 0, 0, 0, 0, 0, 0, 0, 0, 1],
      [1, 0, 1, 1, 0, 0, 0, 0, 0, 1],
      [1, 0, 0, 0, 0, 0, 0, 1, 1, 1],
      [1, 0, 0, 1, 0, 3, 0, 0, 0, 1],
      [1, 0, 0, 0, 0, 0, 0, 1, 0, 1],
      [1, 3, 1, 0, 0, 0, 0, 0, 0, 1],
      [1, 1, 1, 1, 1, 1, 1, 1, 1, 1],
    ];
    
    // Initial position of the player
    let playerPos = { x: 1, y: 1 };
    
    //Populates the maze in the HTML
    function createMaze() {
      main.innerHTML = ''; // Clear existing maze
      for (let y = 0; y < maze.length; y++) {
        for (let x = 0; x < maze[y].length; x++) {
          let block = document.createElement("div");
          block.classList.add("block");
    
          switch (maze[y][x]) {
            case 1:
              block.classList.add("wall");
              break;
            case 2:
              block.id = "player";
              let mouth = document.createElement("div");
              mouth.classList.add("mouth");
              block.appendChild(mouth);
              break;
            case 3:
              block.classList.add("enemy");
              break;
            default:
              block.classList.add("point");
              block.style.height = "1vh";
              block.style.width = "1vh";
          }
    
          main.appendChild(block);
        }
      }
    }
    
    // Move player if the next position is not a wall
    function movePlayer(dx, dy) {
      const newX = playerPos.x + dx;
      const newY = playerPos.y + dy;
      if (maze[newY][newX] !== 1) { // Check for collision with wall
        maze[playerPos.y][playerPos.x] = 0; // Clear current position
        playerPos.x = newX;
        playerPos.y = newY;
        maze[playerPos.y][playerPos.x] = 2; // Update new position
        createMaze(); // Re-create the maze with updated position
      }
    }
    
    function keyUp(event) {
      if (event.key === "ArrowUp") {
        upPressed = false;
        ubutton.style.borderStyle = "outset";
      } else if (event.key === "ArrowDown") {
        downPressed = false;
        dbutton.style.borderStyle = "outset";
      } else if (event.key === "ArrowLeft") {
        leftPressed = false;
        lbutton.style.borderStyle = "outset";
      } else if (event.key === "ArrowRight") {
        rightPressed = false;
        rbutton.style.borderStyle = "outset";
      }
    }
    
    function keyDown(event) {
      if (event.key === "ArrowUp") {
        upPressed = true;
        ubutton.style.borderStyle = "inset";
      } else if (event.key === "ArrowDown") {
        downPressed = true;
        dbutton.style.borderStyle = "inset";
      } else if (event.key === "ArrowLeft") {
        leftPressed = true;
        lbutton.style.borderStyle = "inset";
      } else if (event.key === "ArrowRight") {
        rightPressed = true;
        rbutton.style.borderStyle = "inset";
      }
    }
    
    const lbutton = document.querySelector("#lbttn");
    const rbutton = document.querySelector("#rbttn");
    const ubutton = document.querySelector("#ubttn");
    const dbutton = document.querySelector("#dbttn");
    
    const startBtn = document.querySelector(".start");
    startBtn.addEventListener("click", startGame);
    
    function startGame() {
      document.addEventListener("keydown", keyDown);
      document.addEventListener("keyup", keyUp);
      startBtn.style.display = "none";
    }
    
    setInterval(function () {
      if (downPressed) {
        movePlayer(0, 1);
      } else if (upPressed) {
        movePlayer(0, -1);
      } else if (leftPressed) {
        movePlayer(-1, 0);
      } else if (rightPressed) {
        movePlayer(1, 0);
      }
    }, 200);
    
    createMaze();