我通过中心点距离来判断与哪个元素进行碰撞检测,现在问题是对于wall上方的碰撞检测不起效果
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
<canvas id="canvas" width="500" height="500"></canvas>
</body>
<script>
var canvas = document.getElementById("canvas");
var ctx = canvas.getContext('2d');
var hero = {
height: 50,
width: 30,
x: 10,
y: 10,
speed: 150,
}
var wall = [
{
height: 100,
width: 200,
x: 100,
y: 100,
},
{
height: 50,
width: 50,
x: 300,
y: 300,
}
];
function drawWall() {
ctx.save();
ctx.fillStyle = "#FFA500";
for (let i = 0; i < wall.length; i++) {
ctx.fillRect(wall[i].x, wall[i].y, wall[i].width, wall[i].height);
}
ctx.restore();
}
function drawHero() {
ctx.save();
ctx.fillStyle = "skyblue";
ctx.fillRect(hero.x, hero.y, hero.width, hero.height);
ctx.restore();
}
function draw() {
ctx.clearRect(0, 0, 500, 500);
drawHero();
drawWall();
}
draw();
// 移动
var keyDown = {};
var then = Date.now();
var collision = {
top: false,
left: false,
bottom: false,
right: false,
};
addEventListener('keydown', function (e) {
keyDown[e.keyCode] = true;
}, false)
addEventListener('keyup', function (e) {
delete keyDown[e.keyCode]
}, false)
function move(time) {
if (87 in keyDown) { //W
if (collision.top == true) {
hero.y -= 0
} else {
hero.y -= hero.speed * time
}
}
if (65 in keyDown) { //A
if (collision.left == true) {
hero.x -= 0
} else {
hero.x -= hero.speed * time
}
}
if (83 in keyDown) { //S
if (collision.bottom == true) {
hero.y += 0
} else {
hero.y += hero.speed * time
}
}
if (68 in keyDown) { //D
if (collision.right == true) {
hero.y += 0
} else {
hero.x += hero.speed * time;
}
}
}
function collisionDetection(hero, wall) {
// collision.top = false;
// collision.left = false;
// collision.bottom = false;
// collision.right = false;
if (hero.x <= wall.x) {
if (hero.x + hero.width + 2 >= wall.x && hero.y + hero.height > wall.y && hero.y < wall.y + wall.height) {
collision.right = true;
direction = '右';
} else {
collision.right = false;
direction = ' ';
}
}
if (hero.x >= wall.x + wall.width) {
if (hero.x - 2 <= wall.x + wall.width && hero.y + hero.height > wall.y && hero.y < wall.y + wall.height) {
collision.left = true;
direction = '左';
} else {
collision.left = false;
direction = ' ';
}
}
if (hero.y + hero.height < wall.y) {
if (hero.x - 2 <= wall.x + wall.width && hero.x + hero.width + 2 >= wall.x && hero.y + hero.height + 2 >= wall.y) {
collision.bottom = true;
direction = '下';
} else {
collision.bottom = false;
direction = ' ';
}
}
if (hero.y > wall.y + wall.height) {
if (hero.x - 2 <= wall.x + wall.width && hero.x + hero.width + 2 >= wall.x && hero.y <= wall.y + wall.height + 2) {
collision.top = true;
direction = '上';
} else {
collision.top = false;
direction = ' ';
}
}
console.log(collision.left, collision.top, collision.right, collision.bottom)
}
// 查找和hero最近的元素,并判断碰撞检测
function distance() {
let arr = [];
for (let i = 0; i < wall.length; i++) {
let herox = heroy = wallx = wally = ax = ay = az = 0;
herox = hero.x + hero.width / 2;
heroy = hero.y + hero.height / 2;
wallx = wall[i].x + wall[i].width / 2;
wally = wall[i].y + wall[i].height / 2;
ax = Math.abs(wallx - herox);
ay = Math.abs(wally - heroy);
az = Math.sqrt(ax * ax + ay * ay);
let data = { index: i, num: az };
arr.push(data);
}
let bIndex = arr.sort((a, b) => { return a.num - b.num })[0].index;
collisionDetection(hero, wall[bIndex]);
}
function moveTime() {
var now = Date.now();
var deleta = now - then;
let time = deleta / 1000;
move(time);
draw();
distance();
then = now;
requestAnimationFrame(moveTime);
}
moveTime();
// 移动
</script>
<style>
#canvas {
border: 1px solid #000;
}
</style>
</html>
通过中心点距离来判断与哪个元素进行碰撞检测也有问题, 如下图.

hero中心点与2号墙中心点更近, 但是发生碰撞的墙却是1号墙