如何解决蛇食碰撞检测
我正在用普通的 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 举报,一经查实,本站将立刻删除。