javascript - 在我的 JS 游戏中,蛇不能骑在画布边缘?
问题描述
嘿伙计们,我写了一个条件来检查蛇头的位置,看看它是否撞到了画布的边缘。如果发生这种情况,我不会停止游戏运行的间隔。这是代码//check if snake hit wall
if(headX <= 0 || headY <= 0 || headX >= (cvsW-unit) || headY >= (cvsH-unit)) {
alert(headX);
clearInterval(runGame);
}
,但感觉画布边缘的 x any y 位置为 0,这意味着如果在画布边缘生成食物,蛇将无法在游戏停止的情况下到达那里。如果您将值降低到 0 以下,蛇头现在将能够离开画布。我不知道如何绕过这个请帮助。
const canvas = document.querySelector('#canvas');
const ctx = canvas.getContext('2d');
//set canvas dimension equal to css dimension
canvas.width = 768;
canvas.height = 512;
//now put those dimensions into variables
const cvsW = canvas.width;
const cvsH = canvas.height;
//create snake unit
const unit = 16;
//create snake array
let snake = [{x: cvsW/2, y: cvsH/2}];
//delcare global variable to hold users direction
let direction;
//create food object
let food = {
x : Math.floor(Math.random()*((cvsW/unit)-1)+1)*unit,
y : Math.floor(Math.random()*((cvsH/unit)-1)+1)*unit
}
//read user's direction
document.addEventListener('keydown', changeDirection);
function changeDirection(e) {
//set direction
if (e.keyCode == 37 && direction != 'right') direction = 'left';
else if (e.keyCode == 38 && direction != 'down') direction = 'up';
else if (e.keyCode == 39 && direction != 'left') direction = 'right';
else if (e.keyCode == 40 && direction != 'up') direction = 'down';
}
function draw() {
//refresh canvas
ctx.clearRect(0, 0, cvsW, cvsH);
//draw snake
for(let i = 0; i < snake.length; i++) {
ctx.fillStyle = 'limegreen';
ctx.fillRect(snake[i].x, snake[i].y, unit, unit);
}
//grab head position
let headX = snake[0].x;
let headY = snake[0].y;
//check if snake hit wall
if(headX <= 0 || headY <= 0 || headX >= (cvsW-unit) || headY >= (cvsH-unit)) {
alert(headX);
clearInterval(runGame);
}
//posistion food on board
ctx.fillStyle = 'red';
ctx.fillRect(food.x, food.y, unit, unit);
//send the snake in chosen direction
if(direction == 'left') headX -= unit;
else if(direction == 'up') headY -= unit;
else if(direction == 'right') headX += unit;
else if(direction == 'down') headY += unit;
//create new head
let newHead = {x: headX, y: headY}
if(headX == food.x && headY == food.y) {
//create new food position
food = {
x : Math.floor(Math.random()*((cvsW/unit)-1)+1)*unit,
y : Math.floor(Math.random()*((cvsH/unit)-1)+1)*unit
}
//add 3 units to the snake
snake.unshift(newHead);
snake.unshift(newHead);
snake.unshift(newHead);
}
else {
//remove tail
snake.pop();
}
//add head to snake
snake.unshift(newHead);
}
//run game engine
let runGame = setInterval(draw, 70);
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Snake Game</title>
<style>
body {
background-color: #333;
}
canvas {
background-color: #4d4d4d;
margin: auto;
display: block;
position: absolute;
left: 0;
right: 0;
top: 0;
bottom: 0;
width: 750px;
height: 500px;
}
</style>
</head>
<body>
<canvas id="canvas"></canvas>
<script src="script.js"></script>
</body>
</html>
解决方案
据我了解,您有一个 48x32 网格,其空间为 16px 正方形。您用来生成食物在网格上的位置的算法:
let food = {
x : Math.floor(Math.random()*((cvsW/unit)-1)+1)*unit, // Chooses 1-47
y : Math.floor(Math.random()*((cvsH/unit)-1)+1)*unit // Chooses 1-31
}
为 x 选择 1 到 47 之间的值,为 y 选择 1 到 31 之间的值。好吧,问题在于 x 的位置 47 和 y 的位置 31 都在网格的边缘(这是因为第一个 x/y 位置是 0,而不是 1)。为了消除这些空格作为选择,算法只需从网格上的空格数(即 cvsW 或 cvsH 除以单位)中减去 2 而不是 1:
let food = {
x : Math.floor(Math.random()*((cvsW/unit)-2)+1)*unit, // Chooses 1-46
y : Math.floor(Math.random()*((cvsH/unit)-2)+1)*unit // Chooses 1-30
}
基本上,减 1 只消除了最后一列/行作为 x/y 位置的选择,然后加 1 将所有内容移到右侧。像这样(对于 x):
新算法会这样做,最初消除最后两个选择,然后转移到 1:
推荐阅读
- amazon-web-services - 无法连接到 RDS 写入器端点
- javascript - Firebase:未捕获的语法错误:无效或意外的令牌->未捕获的参考错误
- node.js - NRWL NX - 为什么我在运行“ng serve express”时得到“找不到名称‘describe’”?
- constraint-programming - 载客量受限的载客车辆路线问题
- xslt - XSL 不会写 xmlns:xsl?
- javascript - chartjs:需要 yAxis 比例附近的彩条
- c++ - c ++将模板化函数应用于元组的每个元素
- javascript - 使用 django REST 和 Vue.js 传播不可迭代实例的无效尝试
- ruby-on-rails - 配置异常在生产模式下启动 Web 应用程序 Ruby
- optimization - 在c中具有多重撤消/重做的文本编辑器