Javascript/JQuery 中的多个 DIV 碰撞检测

multiple DIV collision detection in Javascript/JQuery

正在制作一个 "zombies" 或 "tag you're it" 或 "ew! you got cooties" 风格的小游戏,其中每个 AI 对象(基本上是一个人)随机跑来跑去。有一个 "it" 或 "infected" 的初始对象,当它在屏幕上移动并且 touches/overlaps/collides 与另一个对象一起移动时,它应该将触摸的对象更改为与触摸它的对象相同的颜色.新感染的物体可以继续感染它们随机碰撞的其他物体,直到 - 原则上 - 整个种群的颜色与第一个被感染的物体相同。 (稍后我会担心更高级的 AI,其中受感染的人会主动猎杀附近的物体,或者健康的物体可以避开受感染的物体)。

但是在查看 Whosebug 中通常处理 2 个 DIV 碰撞或使用某种 jQuery 可拖动检测技巧的各种类似问题之后,我仍然对如何在这些想法的基础上扩展一个简单的 "if I am touching/overlapping/colliding with another object it should get infected too",它可以应用于页面上的大量元素,比如说......少于 100 个,以免拖累浏览器。

我基本上已经确定了对象的位置和 widths/heights,这样我就知道它们占用了多少 space,但是在尝试开发时大脑会 'bzzzzt'检查所有种群是否发生碰撞的函数。

让人群毫无问题地随机移动 - 有关相关代码,请参阅 JSFiddle https://jsfiddle.net/digitalmouse/5tvyjhjL/1/。受影响的函数应该在 'animateDiv()' 中,如下所示,让 Whosebug 问题询问编辑很高兴我在我的问题中包含了一些代码。 :)

 function animateDiv($target) {
     var newq = makeNewPosition($target.parent());
     var oldq = $target.offset();
     var speed = calcSpeed([oldq.top, oldq.left], newq);

     // I believe collision should be dealt with here,
     // just before moving an object

     $target.animate({
         top: newq[0],
         left: newq[1]
     }, speed, function () {
         animateDiv($target);
     });
 }

感谢任何能将我推向正确方向的提示、技巧、改编或代码片段。

一个快速、低级和肮脏的解决方案(有更复杂的算法)将使用:

document.elementFromPoint(x, y);

获取指定位置的元素。可以在 here.

中找到完整的规范

假设你的 'zombies' 是矩形的,你可以为每个角调用它,如果你被击中,那不是背景或你正在检查的元素,你有碰撞...

编辑:

另一种方法,甚至 'downer and dirtier' 比上面的方法都快,但速度非常快,就是获取要检查的两个对象的中心点,然后找到它们在 X 和 Y 中的绝对位移。如果差异是小于它们宽度和高度的一半的总和,那么它们是重叠的。它绝不是完美的像素,但它应该能够非常快速地处理大量对象。

编辑 2:

首先,我们需要获取每个对象的中心(检查)

// Values for main object
// pop these in vars as we'll need them again in a sec...
hw = object.style.width >> 1; // half width of object
hh = object.style.height >> 1; // (bit shift is faster than / 2)

cx = object.style.left + hw; // centre point in x
cy = object.style.top + hh; // and in y

// repeat for secondary object

如果您不知道/存储宽度和高度,您可以使用:

object.getBoundingClientRect();

其中 returns 一个 'rect' 对象,具有左、上、右和下字段。
现在我们检查接近度...

xDif = Math.abs(cx - cx1); // where cx1 is centre of object to check against

if(xDif > hw + hw1) return false; // there is no possibility of a collision!

// if we get here, there's a possible collision, so...

yDif = Math.abs(cy - cy1);

if(yDif > hh + hh1) return false; // no collision - bug out.
else {
    // handle collision here...
}

丹尼