如何检测快速移动物体之间的碰撞

How to detect collisions between fast moving objects

本文关键字:移动 之间 碰撞 何检测 检测      更新时间:2023-09-26

一般来说,为了检测画布游戏中的碰撞,我使用如下命令:

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;
}

但是这只检测到在处理帧时物体接触的碰撞。如果我有一个精灵,它的速度(以像素/帧为单位)大于其路径上障碍物的宽度,它将在不检测到碰撞的情况下穿过障碍物。

我该如何检查精灵和目的地之间的内容?

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

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

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

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

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

看看这个。试着用方向键移动rect1,如果它碰到rect2,它会提示"碰撞"。

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>