Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/javascript/405.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/html/74.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript 蛇类游戏:如何检查头部是否与自己的身体相撞_Javascript_Html_Algorithm_Canvas_2d Games - Fatal编程技术网

Javascript 蛇类游戏:如何检查头部是否与自己的身体相撞

Javascript 蛇类游戏:如何检查头部是否与自己的身体相撞,javascript,html,algorithm,canvas,2d-games,Javascript,Html,Algorithm,Canvas,2d Games,你可能玩过蛇,一种你必须吃食物才能生长的游戏,如果你与蛇的身体或某些障碍物相撞,你就会失败。第一部分很容易,但后一部分似乎不可能实现 我试图对snake数组的最后一个元素是否与其其他部分发生碰撞进行for循环检查。我的条件是这样的:如果数组中最后一个项的x位置大于任何数组项的x位置,并且小于它们的x位置加上它们的宽度,依此类推。那没用 这是我的密码: <!DOCTYPE html> <html> <head> </head> <body>

你可能玩过蛇,一种你必须吃食物才能生长的游戏,如果你与蛇的身体或某些障碍物相撞,你就会失败。第一部分很容易,但后一部分似乎不可能实现

我试图对snake数组的最后一个元素是否与其其他部分发生碰撞进行
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,