微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

蛇食碰撞检测

如何解决蛇食碰撞检测

我正在用普通的 javascript 制作一个蛇游戏。但现在我来到了游戏的食物部分。但我无法让它正常工作。我有一个食物功能,可以在游戏场内生成随机绳索,然后绘制食物。这首先已经很不稳定了。但后来我想检测蛇线和食物线是否匹配,边距为 20 像素。但我就是不能顺利地把它说出来。

谁能帮我弄清楚出了什么问题以及如何解决这个问题?谢谢!

    let canvas = document.getElementById("canvas");
    let movespeedX = 2;
    let movespeedY = 0;
    var canvasContext = canvas.getContext('2d');
    
    //newest cord
    let locationX = 20;
    let locationY = 20;
    //cords up to snakelength
    let cords = [
        {X: 5,Y: 5}
    ];

    let snakeLength = 5;
    
    //food location
    let foodX;
    let foodY;
    let isfood = false;

    //onload draw,move and set food
    window.onload = function() {
    setInterval(callField => {draw(); move(); food()},1000/60);

    //keyboard controls
    document.addEventListener('keydown',event => {
        const key = event.key.toLowerCase();
        if(key == "w" || key == "arrowup")
        {
            movespeedX = 0;
            movespeedY = -2;
        }
        if(key == "s" || key == "arrowdown")
        {
            movespeedX = 0;
            movespeedY = 2;
        }
        if(key == "a" || key == "arrowleft")
        {
            movespeedY = 0;
            movespeedX = -2;
        }
        if(key == "d" || key == "arrowright")
        {
            movespeedY = 0;
            movespeedX = 2;
        }
    });
    }

    function move()
    {
        //add movespeed to location to move all directions
        locationX += movespeedX;
        locationY += movespeedY;

        //if a wall is hit restart
        if(cords[0].X >= canvas.width || cords[0].X <= 0 || cords[0].Y >= canvas.height || cords[0].Y < 0)
        {
            restart();
        }

        //if food is hit with 20px margin (this is currently verry trippy and does not work)
        if(foodY+20 > cords[0].X && foodY+20 > cords[0].Y)
        {
            isfood = false;
            snakeLength += 5;
        }
        
        //update cords array with newest location
        cords.unshift({X: locationX,Y: locationY});
        if(cords.length > snakeLength)
        {
            delete cords[snakeLength];
        }
    }

    function draw()
    {
        //draw canvas
        drawRect(0,canvas.width,canvas.height,"black");
        //draw food
        drawCircle(foodX,foodY,20,"red");
        //draw snake
        cords.forEach(element => {
            drawCircle(element.X+20,element.Y,"white");
        });
    }
   
    //reset to standard values
    function restart()
    {
        locationX = 20;
        locationY = 20;
        movespeedX = 0;
        movespeedY = 0;
        snakeLength = 1;
        cords = [
            {X: 0,Y: 0}
        ];
    }

    //if the is no food,generate new cords and set food to true
    function food()
    {
        if(isfood === false)
        {
            foodX = Math.floor(Math.random() * canvas.width) + 50;
            foodY = Math.floor(Math.random() * canvas.height) + 50;
            isfood = true;
        }
    }
   
    function drawRect(leftX,topY,width,height,color)
    {
        canvasContext.fillStyle = color;
        canvasContext.fillRect(leftX,height);
    } 
    function drawCircle(leftX,radius,color)
    {
        canvasContext.fillStyle = color;
        canvasContext.beginPath();
        canvasContext.arc(leftX,Math.PI*2,true);
        canvasContext.fill()
    }```

解决方法

使用勾股定理求两个物体的距离,然后对于圆,计算半径加上您可能需要的任何额外缓冲区。

有点像

if (distance < objects.radius + other.objects.radius) {
  return true
}

这是你的代码

let canvas = document.getElementById("canvas");
let movespeedX = 2;
let movespeedY = 0;
var canvasContext = canvas.getContext("2d");
canvas.width = innerWidth;
canvas.height = innerHeight;
//newest cord
let locationX = 20;
let locationY = 20;
//cords up to snakelength
let cords = [{ X: 5,Y: 5 }];

let snakeLength = 5;

//food location
let foodX;
let foodY;
let isfood = false;

//onload draw,move and set food
window.onload = function () {
  setInterval((callField) => {
    draw();
    move();
    food();
  },1000 / 60);

  //keyboard controls
  document.addEventListener("keydown",(event) => {
    const key = event.key.toLowerCase();
    if (key == "w" || key == "arrowup") {
      movespeedX = 0;
      movespeedY = -2;
    }
    if (key == "s" || key == "arrowdown") {
      movespeedX = 0;
      movespeedY = 2;
    }
    if (key == "a" || key == "arrowleft") {
      movespeedY = 0;
      movespeedX = -2;
    }
    if (key == "d" || key == "arrowright") {
      movespeedY = 0;
      movespeedX = 2;
    }
  });
};

function move() {
  //add movespeed to location to move all directions
  locationX += movespeedX;
  locationY += movespeedY;

  //if a wall is hit restart
  if (
    cords[0].X >= canvas.width ||
    cords[0].X <= 0 ||
    cords[0].Y >= canvas.height ||
    cords[0].Y < 0
  ) {
    restart();
  }

  //if food is hit with 20px margin (this is currently verry trippy and does not work)
  let dx = foodX - cords[0].X;
  let dy = foodY - cords[0].Y;
  let dist = Math.hypot(dx,dy);
  if (dist < 60) {
    isfood = false;
    snakeLength += 5;
  }

  //update cords array with newest location
  cords.unshift({ X: locationX,Y: locationY });
  if (cords.length > snakeLength) {
    delete cords[snakeLength];
  }
}

function draw() {
  //draw canvas
  drawRect(0,canvas.width,canvas.height,"black");
  //draw food
  drawCircle(foodX,foodY,20,"red");
  //draw snake
  cords.forEach((element) => {
    drawCircle(element.X + 20,element.Y,"white");
  });
}

//reset to standard values
function restart() {
  locationX = 20;
  locationY = 20;
  movespeedX = 0;
  movespeedY = 0;
  snakeLength = 1;
  cords = [{ X: 0,Y: 0 }];
}

//if the is no food,generate new cords and set food to true
function food() {
  if (isfood === false) {
    foodX = Math.floor(Math.random() * canvas.width) + 50;
    foodY = Math.floor(Math.random() * canvas.height) + 50;
    isfood = true;
  }
}

function drawRect(leftX,topY,width,height,color) {
  canvasContext.fillStyle = color;
  canvasContext.fillRect(leftX,height);
}
function drawCircle(leftX,radius,color) {
  canvasContext.fillStyle = color;
  canvasContext.beginPath();
  canvasContext.arc(leftX,Math.PI * 2,true);
  canvasContext.fill();
}
<canvas id="canvas"></canvas>

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。