JavaScript碰撞检测矩形和一组边界坐标?

时间:2011-10-18 04:29:36

标签: jquery javascript-events collision

我一直在寻找在SO(以及其他地方)发布的类似问题,但他们似乎只处理矩形,我现在可以很好地处理,或者比我目前能够解决的问题更复杂。

我正在通过mousedown事件在屏幕上移动一个精灵,并希望锁定它不会移动“越界”。边界可能像这个房间一样简单:

绿色是可移动的空间,红色是受限制的。我最好将其分解为类似于1个长矩形和2个三角形(或者用正方形组来表示带有锯齿状边缘的三角形)或者是否有一个基本概念,我应该注意指定“可行走区域”的坐标并验证用户是否始终“在界限内”?

我在JavaScript中对此进行编码,并且在很大程度上依赖于jQuery。

编辑:考虑到我可能需要拥有无限分(如果房间超过4分),我会更好地使用像A *这样的东西来生成路径吗?

4 个答案:

答案 0 :(得分:4)

尝试解构一下你的问题。使用这个简单的形状,你有一个矩形,需要在两个斜面之间有x坐标,两个扁平线之间有y坐标。

这样的事情应该很好用:

function outOfBounds(point, boundary) {
    return point.y > boundary.top
        || point.y < boundary.bottom
        || point.x < boundary.getLeftBoundAt(point.y)
        || point.x > boundary.getRightBoundAt(point.y);
}

回想一下,斜线可以定义为mx + b,但在这种情况下,斜率的x坐标会相对于y坐标变化。无论如何,getLeftBoundAt()看起来像:

function getLeftBoundAt(y) {
    return this.slope * y + this.base;
}

编辑:

由于高度沿左右边缘变化的事实,你需要一个稍微复杂的解决方案,其中boundary.top被调用这样的函数替换:

function getTopBoundAt(x) {
    var segment = this.topSegmentAt(x);
    return segment.origin.y + segment.slope * (x - segment.origin.x);
}

答案 1 :(得分:1)

简单,连续允许区域的另一种可能性是,您可以简单地包含类似于问题中提供的低分辨率地图,并将x / y坐标转换为图像坐标。如果像素在相应的位置点是绿色的,那么你很高兴。这可能非常快,也很容易实现。

这有点像黑客吗?也许,是的......但我认为这也是一个非常有趣的解决方案。

答案 2 :(得分:1)

最常见的解决方案是将零件解构为三角形,然后进行重叠测试,或者将其渲染为像素化位图,并进行一次像素比较。

前者称为曲面细分或三角形多边形:

http://en.wikipedia.org/wiki/Polygon_triangulation

并且具有比O(n ^ 2)更好的好处。有很多算法可以做到这一点,主要是因为3-D引擎需要生成三角形列表以交给图形加速器硬件,这些硬件通常采用[x,y]坐标的三元组信息。

后者不幸的是O(n ^ 2),但允许你做一些事情,比如检查位图的alpha,这样在图片中“清晰”的东西(alpha零或某些截止)不计算。因此,你做了一些有趣的事情,比如确定两个重叠的像素是否结合起来足够“稳固”以进行碰撞,从而使“模糊”的部分-α位图飞来飞去。这个例子不包括alpha,用于android,但是这个例子通常都有:

https://gamedev.stackexchange.com/questions/23603/how-to-handle-pixel-perfect-collision-detection-with-rotation

可在此处找到一些其他信息:

A simple algorithm for polygon intersection

https://gamedev.stackexchange.com/questions/33553/what-algorithms-exist-for-generating-collision-geometry-from-an-image

注意:如果你想使用矩形,包括以近似形状堆叠的一堆矩形作为碰撞的边界,那么(完全公开)我为此制作了一个jQuery插件。既然你说你很依赖jQuery:

https://sourceforge.net/projects/jquerycollision/

答案 3 :(得分:0)

我将YourPalAl的回答标记为正确,但如果其他人偶然发现,我想留下我的最终解决方案。

我现在正在使用jQuery SVG(http://keith-wood.name/svg.html)根据需要插入SVG多边形坐标来定义边界,并在5像素容差内检查对象“下一个目标”范围。如果下一个目标击中多边形,我会阻止对象进一步移动。