Javascript 蛇类游戏:如何检查头部是否与自己的身体相撞
你可能玩过蛇,一种你必须吃食物才能生长的游戏,如果你与蛇的身体或某些障碍物相撞,你就会失败。第一部分很容易,但后一部分似乎不可能实现 我试图对snake数组的最后一个元素是否与其其他部分发生碰撞进行Javascript 蛇类游戏:如何检查头部是否与自己的身体相撞,javascript,html,algorithm,canvas,2d-games,Javascript,Html,Algorithm,Canvas,2d Games,你可能玩过蛇,一种你必须吃食物才能生长的游戏,如果你与蛇的身体或某些障碍物相撞,你就会失败。第一部分很容易,但后一部分似乎不可能实现 我试图对snake数组的最后一个元素是否与其其他部分发生碰撞进行for循环检查。我的条件是这样的:如果数组中最后一个项的x位置大于任何数组项的x位置,并且小于它们的x位置加上它们的宽度,依此类推。那没用 这是我的密码: <!DOCTYPE html> <html> <head> </head> <body>
for
循环检查。我的条件是这样的:如果数组中最后一个项的x
位置大于任何数组项的x
位置,并且小于它们的x
位置加上它们的宽度,依此类推。那没用
这是我的密码:
<!DOCTYPE html>
<html>
<head>
</head>
<body>
<canvas id="myCanvas" width="200px" height="200px" style="border:1px solid black"/>
<script>
var canvas = document.getElementById("myCanvas");
var ctx = canvas.getContext("2d");
var yPos = 20;
var width = 15;
var variable = 1;
var currentDir = 1;
//var xPos = (width+5)*variable;
var xPos = 20;
var myArr = [{myX:xPos,myY:yPos},{myX:xPos,myY:yPos},{myX:xPos,myY:yPos}];
var downPressed = false;
var upPressed = false;
var leftPressed = false;
var rightPressed = false;
var first = [0,20,40,60,80,100,120,140,160,180];
var firstX = Math.floor(Math.random()*10);
var firstY = Math.floor(Math.random()*10);
var okayed = first[firstX];
var notOkayed = first[firstY];
var maths = myArr[myArr.length-1];
function drawFood() {
ctx.beginPath();
ctx.rect(okayed,notOkayed,15,15);
ctx.fillStyle = "red";
ctx.fill();
ctx.closePath();
}
function drawRectangle() {
ctx.clearRect(0,0,200,200);
drawFood();
for(var i = 0;i<myArr.length;i++) {
ctx.beginPath();
ctx.rect(myArr[i].myX,myArr[i].myY,width,15);
ctx.fillStyle = "blue";
ctx.fill();
ctx.closePath();
}
requestAnimationFrame(drawRectangle);
}
setInterval("calledin()",100);
function calledin() {
var secondX = Math.floor(Math.random()*10);
var secondY = Math.floor(Math.random()*10);
var newobj = {myX:myArr[myArr.length-1].myX+20,myY:myArr[myArr.length-1].myY};
var newobjTwo = {myX:myArr[myArr.length-1].myX,myY:myArr[myArr.length-1].myY+20};
var newobjLeft = {myX:myArr[myArr.length-1].myX-20,myY:myArr[myArr.length-1].myY};
var newobjUp = {myX:myArr[myArr.length-1].myX,myY:myArr[myArr.length-1].myY-20};
var okayNewObj = {myX:myArr[1].myX - 20,myY:myArr[1].myY};
if(myArr[myArr.length-1].myX > 180 || myArr[myArr.length-1].myX < 0 || myArr[myArr.length-1].myY > 180 || myArr[myArr.length-1].myY < 0)
{alert("Game Over");window.location.reload();}
if(myArr[myArr.length-1].myX > okayed-5 && myArr[myArr.length-1].myX < okayed+20 && myArr[myArr.length-1].myY < notOkayed+20 &&
myArr[myArr.length-1].myY > notOkayed-5) {
okayed = first[secondX];
notOkayed = first[secondY];
myArr.unshift(okayNewObj);
}
if(currentDir == 1) {
myArr.push(newobj);
myArr.shift();}
if(currentDir == 2) {
myArr.push(newobjTwo);
myArr.shift();
}
if(currentDir == 4) {
myArr.push(newobjLeft);
myArr.shift();
}
if(currentDir == 3) {
myArr.push(newobjUp);
myArr.shift();
}
for(var i = 0;i<myArr.length-2;i++) {
if(myArr[myArr.length-1].myX > myArr[i].myX &&
myArr[myArr.length-1].myX < myArr[i].myX + 15 && myArr[myArr.length-1].myY > myArr[i].myY && myArr[myArr.length-1].myY > myArr[i].myY + 15)
{alert("Game over");window.location.reload();}
}
}
function downed(e) {
if(e.keyCode==40) {if(currentDir != 3) {currentDir = 2;}}
if(e.keyCode==38) {if(currentDir != 2) {currentDir = 3;}}
if(e.keyCode==39) {if(currentDir != 4) {currentDir = 1;}}
if(e.keyCode==37) {if(currentDir != 1) {currentDir = 4;}}
}
function upped(e) {
if(e.keyCode == 40) {downPressed = false;}
}
document.addEventListener("keydown",downed,false);
document.addEventListener("keyup",upped,false);
drawRectangle();
</script>
</body>
</html>
var canvas=document.getElementById(“myCanvas”);
var ctx=canvas.getContext(“2d”);
var-yPos=20;
var宽度=15;
var变量=1;
var currentDir=1;
//var xPos=(宽度+5)*变量;
var-xPos=20;
var myArr=[{myX:xPos,myY:yPos},{myX:xPos,myY:yPos},{myX:xPos,myY:yPos}];
var-downPressed=false;
var upPressed=假;
var leftPressed=false;
var-rightspressed=false;
var first=[0,20,40,60,80100120140160180];
var firstX=Math.floor(Math.random()*10);
var firstY=Math.floor(Math.random()*10);
var okayed=第一个[firstX];
var notOkayed=第一个[第一个];
var Math=myArr[myArr.length-1];
功能食品{
ctx.beginPath();
ctx.rect(okayed,notOkayed,15,15);
ctx.fillStyle=“红色”;
ctx.fill();
ctx.closePath();
}
函数drawRectangle(){
ctx.clearRect(0,0200200);
食物;
对于(变量i=0;i 180 | | myArr[myArr.length-1]。myX<0 | | myArr[myArr.length-1]。myY>180 | | myArr[myArr.length-1]。myY<0)
{alert(“游戏结束”);window.location.reload();}
如果(myArr[myArr.length-1].myX>okayed-5&&myArr[myArr.length-1].myXnotokyed-5){
okayed=第一个[第二个X];
notOkayed=第一[第二];
myArr.unshift(okayNewObj);
}
如果(currentDir==1){
myArr.push(newobj);
myArr.shift();}
如果(currentDir==2){
myArr.push(新目标推送);
myArr.shift();
}
if(currentDir==4){
myArr.push(newobjLeft);
myArr.shift();
}
如果(currentDir==3){
myArr.push(新奥布朱普);
myArr.shift();
}
对于(var i=0;i myArr[i].myX&&
myArr[myArr.length-1]。myXmyArr[i]。myY&&myArr[myArr.length-1]。myY>myArr[i]。myY+15)
{alert(“游戏结束”);window.location.reload();}
}
}
功能已关闭(e){
if(e.keyCode==40){if(currentDir!=3){currentDir=2;}}
if(e.keyCode==38){if(currentDir!=2){currentDir=3;}}
if(e.keyCode==39){if(currentDir!=4){currentDir=1;}}
if(e.keyCode==37){if(currentDir!=1){currentDir=4;}}
}
功能升级(e){
如果(e.keyCode==40){downPressed=false;}
}
文件。添加的监听器(“向下键”,向下键,错误);
文件。添加的监听器(“keyup”,upped,false);
drawRectangle();
假设蛇由一个名为snake
的数组表示,其中头部位于索引snake.length-1
。我们必须在指数0
到snake.length-2
时,将头部位置与身体各部分的位置进行比较
如果蛇头与身体部分碰撞,以下代码将ok
设置为false
。否则,正常
将保持正确
var head = snake[snake.length - 1],
x = head.x,
y = head.y,
okay = true;
for (var i = snake.length - 2; i >= 0; --i) {
if (snake[i].x == x && snake[i].y == y) {
okay = false;
break;
}
}
下面是一个片段,我在其中修改了您的代码,以澄清游戏逻辑并简化许多计算
我没有直接使用画布坐标,而是使用虚拟网格单元的列索引x
和行索引y
表示每个位置。这使我们可以通过向x
或y
添加1或-1来计算相邻栅格位置。当绘制画布时,我们将虚拟坐标乘以单元大小
我已经用变量替换了大多数文本值。例如,我们可以执行以下操作,而不是将画布尺寸设置为200 x 200:
canvas.width = numCols * cellSize;
canvas.height = numRows * cellSize;
这让我们可以在一个地方更改numCols
和numRows
以调整整个游戏网格的大小。所有的计算都是有效的,因为它们计算变量而不是使用文字
我修改了按键事件处理,以识别除箭头键外的W-A-S-D键的按键代码。当游戏嵌入一个长网页时,就像这里一样,你可能会想使用W-a-S-D键,这样当你玩游戏时,网页就不会上下滚动
var画布,
ctx,
currentDir,
startX=1,
startY=1,
startSnakeLength=3,
蛇,
单元大小=18,
cellGap=1,
foodColor='#a2302a',
蛇体颜色='#2255a2',
蛇头色='#0f266b',
numRows=10,
numCols=10,
canvasWidth=numCols*单元格大小,
画布高度=numRows*单元格大小;
var食品={};
功能食品{
//找到一个不被蛇占据的随机位置。
var-ok=false;
而(!好的){
food.x=Math.floor(Math.random()*numCols);
food.y=Math.floor(Math.random()*numRows);
OK=正确;
对于(变量i=0;i=0;--i){
paintCell(snake[i].x,snake[i].y,snakeBodyColor);
}
}
函数updateGame(){
var head=snake[snake.length-1],
x=头部x,