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...
}
丹尼
正在制作一个 "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...
}
丹尼