我的JS游戏中蛇不能在画布边缘骑行吗?

时间:2019-01-16 05:19:28

标签: javascript

伙计们,我写了一个条件来检查蛇头的位置,看它是否碰到了画布的边缘。如果发生这种情况,我将不停止游戏运行的间隔。这是代码//check if snake hit wall if(headX <= 0 || headY <= 0 || headX >= (cvsW-unit) || headY >= (cvsH-unit)) { alert(headX); clearInterval(runGame); } 但是感觉到画布的边缘的x y位置为0,这意味着如果在画布的边缘上产生了食物,那么在不停止游戏的情况下,蛇就不能去那里。如果将值降低到0以下,则蛇头现在将可以移出画布。我不知道该如何避开这个plz帮助。

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>

1 个答案:

答案 0 :(得分:1)

据我了解,您有一个48x32的网格,其空间为16像素正方形。用于生成食物在网格上的位置的算法:

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):

enter image description here

新算法执行此操作,首先消除了最后两个选择,然后移至1:

enter image description here