为什么当蛇吃了苹果后代码就不起作用了?

3
大家下午好。我正在制作我的贪吃蛇游戏。当我实现了贪吃蛇吃苹果的功能时,遇到了一个问题(应该在贪吃蛇吃苹果时启动的函数无法正常使用)。
我尝试将苹果的位置与块的大小进行比较。当贪吃蛇吃掉苹果时,函数应该返回一个警告。

var canvas = document.getElementById("game");
var ctx = canvas.getContext("2d");
var box = 10;

//Snake
var snake = [];
var px = canvas.width / 2;
var py = canvas.height / 2;
var dir = "right";
var maxCell = 10;
var can = canvas.getBoundingClientRect();

//Apple
var ax = Math.floor(Math.random() * ~~(canvas.width / box));
var ay = Math.floor(Math.random() * ~~(canvas.height / box));

document.addEventListener("keydown", function(e) {
  if (e.keyCode === 37 && dir !== "right") {
    dir = "left";
    //console.log('left')
  } else if (e.keyCode === 38 && dir !== "down") {
    dir = "up";
    //console.log('up')
  } else if (e.keyCode === 39 && dir !== "left") {
    dir = "right";
    //console.log('right')
  } else if (e.keyCode === 40 && dir !== "up") {
    dir = "down";
    //console.log('down')
  }
});

function direction() {
  if (dir == "right") {
    px += box;
  } else if (dir == "left") {
    px -= box;
  } else if (dir == "up") {
    py -= box;
  } else if (dir == "down") {
    py += box;
  }
}

//Closure )))
function Elems() {
  //! Spawn apple
  function Apple() {
    ctx.fillStyle = "green";
    ctx.fillRect(ax, ay, box, box);
  }

  //! Spawn snake
  function Snake() {
    direction();
    var head = {
      x: px,
      y: py,
    };
    snake.unshift(head);

    if (snake.length < maxCell) {
      snake.push({
        x: px,
        y: py
      });
    }

    if (px >= canvas.width) {
      px = 0;
    } else if (px < 0) {
      px = canvas.width;
    }
    if (py >= canvas.height) {
      py = 0;
    } else if (py < 0) {
      py = canvas.height;
    }
    snake.forEach(function(elem, index) {
      ctx.fillStyle = `red`;
      ctx.fillRect(elem.x, elem.y, box, box);
    });

    //BROKEN CODE
    if (head.x == ax && head.y == ay) {
      alert("HI");
    }
    snake.pop();
  }

  Snake();
  Apple();
}

function loop() {
  setInterval(() => {
    ctx.clearRect(0, 0, canvas.width, canvas.height);
    Elems();
  }, 2000 / 30);
}

loop();
canvas {
  border: 1px solid #000;
  background-color: #000;
}
<canvas id="game" width="450" height="450"></canvas>

2个回答

3

您正在检查相等性:

if (head.x == ax && head.y == ay) {
  alert("HI");
}

你必须检查是否有重叠。苹果不是一个点,而是一个区域。你需要检查这两个区域是否相互重叠。(苹果的区域和蛇头的区域)

问题在于你有两个矩形,它们是否重叠?

第二种解决方案:你可以以某种方式设置苹果的位置,使你目前的代码可以工作。目前,你正在随机在画布上生成苹果,如果你能修复这个问题,那么你现在的代码可能就可以工作。

基本上,当蛇吃掉苹果时,你将确保苹果的角落和蛇头的角落相等。如果你可以修复苹果生成的代码,它可能就可以工作了。


我明白了。但是,我该如何修复它呢?你有什么想法或建议吗? - Phantom
1
@Phantom 在一张纸上画两个重叠的矩形。已知每个矩形的坐标,如何确定它们是否重叠? - Lee Taylor
虽然我不是这个领域的专家,但是这个方法能帮上忙吗?getBoundingClientRect()。https://developer.mozilla.org/en-US/docs/Web/API/Element/getBoundingClientRect - Chris G
它不起作用。你可以做到这一点。确保你的蛇和苹果的初始坐标是10的倍数。x位置和y位置将是10的倍数。在这种情况下,你当前的代码将会起作用。 - Kadir Korkmaz

2

如果你的方块是10x10,那么你需要计算出网格。在你的情况下,你有一个450 x 450像素的画布,你将其除以10,网格将是45x45。

使用grid.x和grid.y(这些是您网格中的最大值)来放置蛇并生成苹果坐标。

这样,你只需要检查左上角的坐标,而不是矩形是否重叠。

var canvas = document.getElementById("game");
var ctx = canvas.getContext("2d");
var box = 10;
//calculate your grid
var grid = {
  x: Math.floor(canvas.width / box),
  y: Math.floor(canvas.height / box)
};

var snake = [];
//use grid to center the snake
var px = Math.floor(grid.x / 2) * box;
var py = Math.floor(grid.y / 2) * box;
var dir = "right";
var maxCell = 10;
var can = canvas.getBoundingClientRect();

//Apple
//use your grid to spawn an apple
var ax = Math.floor(Math.random() * grid.x) * box;
var ay = Math.floor(Math.random() * grid.y) * box;

document.addEventListener("keydown", function(e) {
  if (e.keyCode === 37 && dir !== "right") {
    dir = "left";
    //console.log('left')
  } else if (e.keyCode === 38 && dir !== "down") {
    dir = "up";
    //console.log('up')
  } else if (e.keyCode === 39 && dir !== "left") {
    dir = "right";
    //console.log('right')
  } else if (e.keyCode === 40 && dir !== "up") {
    dir = "down";
    //console.log('down')
  }
});

function direction() {
  if (dir == "right") {
    px += box;
  } else if (dir == "left") {
    px -= box;
  } else if (dir == "up") {
    py -= box;
  } else if (dir == "down") {
    py += box;
  }
}

//Closure )))
function Elems() {
  //! Spawn apple
  function Apple() {
    ctx.fillStyle = "green";
    ctx.fillRect(ax, ay, box, box);
  }

  //! Spawn snake
  function Snake() {
    direction();
    var head = {
      x: px,
      y: py,
    };
    snake.unshift(head);

    if (snake.length < maxCell) {
      snake.push({
        x: px,
        y: py
      });
    }

    if (px >= canvas.width) {
      px = 0;
    } else if (px < 0) {
      px = canvas.width;
    }
    if (py >= canvas.height) {
      py = 0;
    } else if (py < 0) {
      py = canvas.height;
    }
    snake.forEach(function(elem, index) {
      ctx.fillStyle = `red`;
      ctx.fillRect(elem.x, elem.y, box, box);
    });
    //BROKEN CODE
    if (head.x == ax && head.y == ay) {
      alert("HI");
    }
    snake.pop();
  }

  Snake();
  Apple();
}

function loop() {
  setInterval(() => {
    ctx.clearRect(0, 0, canvas.width, canvas.height);
    Elems();
  }, 2000 / 30);
}

loop();
canvas {
  border: 1px solid #000;
  background-color: #000;
}
<canvas id="game" width="450" height="450"></canvas>


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接