- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
谁能告诉我怎么做才能让食物不会在我的蛇体内生成?我已经尝试使用 for
循环来检查蛇的每个索引,看它是否与食物的位置匹配,但这仍然不起作用。
此外,我还加快了游戏速度和蛇吃食物时添加的单位数量,以加快结果并检查该方法是否真的有效。
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;
//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;
// //check if snake hit wall
// if(headX < 0 || headY < 0 || headX > (cvsW-unit) || headY > (cvsH-unit)) {
// clearInterval(runGame);
// }
if (headX < 0) headX = cvsW - unit;
else if (headX > cvsW - unit) headX = 0;
else if (headY < 0) headY = cvsH - unit;
else if(headY > cvsH - unit) headY = 0;
// for(let i = 0; i < snake.length; i++) {
// if(headX == snake[i].x && headY == snake[i].y) {
// clearInterval(game);
// }
// }
//create new head
let newHead = {x: headX, y: headY}
//if snake eats food -do this
if(headX == food.x && headY == food.y) {
//create new food position
while(!checkSnakeForFood()) {
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
for (let i = 30; i > 0; i--) {
snake.unshift(newHead);
}
}
else {
//remove tail
snake.pop();
}
//add head to snake
snake.unshift(newHead);
}
//run game engine
let runGame = setInterval(draw, 40);
function checkSnakeForFood() {
for(let i = 0; i < snake.length; i++) {
if(snake[i].x === food.x && snake[i].y === food.y) return false;
}
return true;
}
<!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>
最佳答案
问题是 checkSnakeForFood()
没有像您预期的那样工作,因为在您测试食物-头部碰撞时 newHead
尚未添加到蛇体中。
只有蛇尾被检查并且 checkSnakeForFood()
例程报告当前食物放置(在 newHead
正下方)不是碰撞,所以 while
循环体没有被执行并且食物没有移动。这是正在发生的事情的图表:
0123456789
0+---------
1|.........
2|.F######.
3|.......##
^^^^^^^
|
only these segments get
tested for collision
newHead
和 food
有相同的位置, [2, 2]
,由 F
表示。他们在碰撞,所以 if (headX == food.x && headY == food.y)
是真的。但是,当在下一行调用 checkSnakeForFood()
时,在循环 #
中只考虑尾部 for (let i = 0; i < snake.length; i++)
元素。然后 checkSnakeForFood()
返回 true 并且 while
循环永远不会重新定位食物。
您可以在尝试调用 unshift
之前通过 newHead
ing checkSnakeForFood()
解决此问题,如下所示:
//create new head
let newHead = {
x: headX,
y: headY
}
//add head to snake, *before* checking for collision with the food
snake.unshift(newHead);
//if snake eats food -do this
if (headX == food.x && headY == food.y) {
//create new food position
while (!checkSnakeForFood()) { // <-- now this will successfully detect
// that the snake head is touching the food
现在,食物与头部的碰撞将正确记录,并且食物将重新定位,直到它不与蛇的尾部或头部碰撞:
0123456789
0+---------
1|.........
2|.F######.
3|.......##
^^^^^^^^
|
all segments are correctly
tested for collision
但是,我建议进行重构以帮助避免此类错误。您可以使 snake
成为具有碰撞和移动成员函数及其 direction
和 tail
属性的对象。您的 draw
函数负担过重,其职责远远超出其名称所 promise 的范围。
分离 newHead
似乎是一种容易出错的方法;直接在阵列上操纵头部可以避免很多困惑。
与此同时,这里是更新后的代码,可以让您再次行动起来(记得点击片段中的 Full page
链接才能正常玩游戏:
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;
//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;
// //check if snake hit wall
// if(headX < 0 || headY < 0 || headX > (cvsW-unit) || headY > (cvsH-unit)) {
// clearInterval(runGame);
// }
if (headX < 0) headX = cvsW - unit;
else if (headX > cvsW - unit) headX = 0;
else if (headY < 0) headY = cvsH - unit;
else if (headY > cvsH - unit) headY = 0;
// for(let i = 0; i < snake.length; i++) {
// if(headX == snake[i].x && headY == snake[i].y) {
// clearInterval(game);
// }
// }
//create new head
let newHead = {
x: headX,
y: headY
}
//add head to snake
snake.unshift(newHead);
//if snake eats food -do this
if (headX == food.x && headY == food.y) {
//create new food position
while (!checkSnakeForFood()) {
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
for (let i = 30; i > 0; i--) {
snake.unshift(newHead);
}
} else {
//remove tail
snake.pop();
}
}
//run game engine
let runGame = setInterval(draw, 40);
function checkSnakeForFood() {
for (let i = 0; i < snake.length; i++) {
if (snake[i].x === food.x && snake[i].y === food.y) return false;
}
return true;
}
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;
}
<canvas id="canvas"></canvas>
关于javascript - 防止食物在我的蛇体内产生,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54263835/
我是编程新手,并且卡在涉及蛇方向改变的特定部分上。该游戏与旧诺基亚手机上的游戏相同。很经典。 目前,每次我按 W、A、S 或 D 键,蛇都会移动 1 平方/20 像素。问题是我希望这个 Action
如果您熟悉任何梦幻体育选秀,选秀顺序网格如下所示: EXAMPLE 1 (3-teams): Round Team 1 Team 2 Team 3 1 1 (1.1) 2 (
我从这里得到了蛇算法的代码(在MatLab中实现) http://www.mathworks.com/matlabcentral/fileexchange/28109-snakes-active-co
我遵循了这个 link 中的示例.然而,轮廓从初始点开始收缩。是否可以做展开的轮廓?我想要像显示的图像那样的东西。左边的图像是它的样子,右边的图像是我想要的样子——向外扩展而不是收缩。红色圆圈为起点,
我正在编写一款类似于贪吃蛇的游戏。目前,我正在努力编写 move() 和 Growth() 方法。这个游戏的运作方式是,蠕虫从 1 block 开始,每 move 一步就增加 1 block ,直到达
说明 我目前正在使用 Pygame 开发蛇游戏,但我遇到了一个问题,因为我的蛇目前仅由方 block 组成,但如果蛇包含蛇头、 body 、尾部的绘制 25x25 图片,我会发现它会更好对于弯曲的 b
我是一名优秀的程序员,十分优秀!