11

通常为了检测画布游戏中的碰撞,我使用类似的东西:

function collides(a, b) {
   return a.x < b.x + b.width &&
     a.x + a.width > b.x &&
     a.y < b.y + b.height &&
     a.y + a.height > b.y;
}

但这仅在处理帧时对象正在接触时才检测到碰撞。如果我有一个精灵,其速度(以像素/帧为单位)大于其路径中障碍物的宽度,它将通过障碍物而不会检测到碰撞。

我将如何检查精灵与其目的地之间的内容?

4

3 回答 3

2

这通常是一个难题,对于像 Box 2D 库这样的高质量解决方案将很有用。

一个快速而肮脏的解决方案(在对角线移动的对象上给出误报)——检查覆盖当前帧和前一帧中对象位置的边界框之间的碰撞。

代替a.x使用min(a.x, a.x - a.velocity_x),代替a.x + a.width使用max(a.x + a.width, a.x + a.width - a.velocity_x)等。

如果快速移动的对象很小(子弹),则测试线(从其原点到原点+速度)与其他对象的盒子之间的碰撞。

于 2013-05-09T15:53:37.513 回答
0

您应该使用移动对象扫过的整个区域(在更新间隔内)作为边界框来检查障碍物。

于 2013-05-09T13:03:06.430 回答
-1

看一下这个。尝试用箭头键移动 rect 1,如果它碰到 rect 2,它会提示“碰撞”。

var rect1x = 0;
var rect1y = 0;
var rect1height = 10;
var rect1width = 10;
var rect2x = 200;
var rect2y = 0;
var rect2height = 10;
var rect2width = 10;
var speedX = 0;
var speedY = 0;
var ctx = document.getElementById("canvas").getContext("2d");
var interval = setInterval(function() {
document.addEventListener("keydown", function(e) {
if (e.key == "ArrowLeft") {
speedX = -1;
}
if (e.key == "ArrowRight") {
speedX = 1;
}
if (e.key == "ArrowUp") {
speedY = -1;
}
if (e.key == "ArrowDown") {
speedY = 1;
}
});
document.addEventListener("keyup", function() {
speedX = 0;
speedY = 0;
});
ctx.clearRect(rect1x, rect1y, rect1width, rect1height);
rect1x += speedX;
rect1y += speedY;
ctx.fillStyle = "blue";
ctx.fillRect(rect1x, rect1y, rect1width, rect1height);
ctx.fillStyle = "red";
ctx.fillRect(rect2x, rect2y, rect2width, rect2height);
if (((rect1x + rect1width > rect2x) && (rect1x < rect2x + rect2width)) && ((rect1y + rect1height > rect2y) && (rect1y < rect2y + rect2height))) {
clearInterval(interval);
alert("collided");
}
}, 0);
<canvas id="canvas" height="400" width="400" style="border: 1px solid black"></canvas>

于 2022-01-19T10:01:12.950 回答