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

发布于 2024-12-10 14:40:25 字数 454 浏览 0 评论 0原文

我一直在查看 Stack Overflow(和其他地方)上发布的类似问题,但它们似乎要么只处理矩形(我目前可以很好地处理),要么比我目前能理解的更复杂。

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

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

我用 JavaScript 进行编码,并且严重依赖 jQuery。

编辑:考虑到我可能需要无限的点(如果房间有超过 4 个点),我最好使用 A* 之类的东西来生成路径吗?

I've been looking at similar questions posted on Stack Overflow (and elsewhere) but they seem to either only deal with rectangles, which I can handle well at this point, or are more complex than I can currently wrap my head around.

I'm moving a sprite around the screen via mousedown events and want to lock it from moving "out of bounds". The bounds could be something simple like this room:

Where the green is movable space and the red is restricted. Am I better off breaking this down into something like 1 long rectangle and 2 triangles (or groups of squares to represent a triangle with jagged edges) or is there a basic concept that I should look towards to specify the coordinates of the "walkable area" and verify that the user is always "within bounds"?

I'm coding this in JavaScript and am relying heavily on jQuery.

Edit: Considering I'd potentially need to have limitless points (if the room had more than 4 points) would I be better off using something like A* to generate the paths?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

逆蝶 2024-12-17 14:40:25

尝试稍微解构你的问题。通过这个简单的形状,您将得到一个矩形,该矩形需要在两个斜率之间具有 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;
}

编辑:

由于高度也沿左右边缘变化,您将需要一个稍微复杂的解决方案,其中 border.top 被替换为对函数的调用像这样:

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

Try deconstructing your problem a bit. With this simple shape, you have a rectangle that needs to have x-coordinates between two slopes, and y-coordinates between two flat lines.

Something like this should work nicely:

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

Recall that sloped lines can be defined as mx + b, but in this case, the x-coordinate of your slopes varies in relation to the y coordinate. Anyway, getLeftBoundAt() will look something like:

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

EDIT:

Due to the fact that the height varies along the left and right edges as well, you would need a slightly more complex solution, where boundary.top is replaced with a call to a function like this:

function getTopBoundAt(x) {
    var segment = this.topSegmentAt(x);
    return segment.origin.y + segment.slope * (x - segment.origin.x);
}
七秒鱼° 2024-12-17 14:40:25

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

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

Another possibility for simple-ish, contiguous allowable areas is that you could simply include a low-res map similar to the one provided in your question, and convert x/y coordinates to image coordinates. If the pixel is at the corresponding location point is green, you're good to go. This could potentially be very fast, and also simple to implement.

Is this a bit of a hack? Maybe, yes... but I think it's also a pretty fun solution.

一袭白衣梦中忆 2024-12-17 14:40:25

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

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

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

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

不幸的是,后者的时间复杂度为 O(n^2),但允许您执行诸如检查位图的 alpha 之类的操作,以便图片中“清晰”的内容(alpha 零或某些截止值)不计算在内。因此,您可以做一些有趣的事情,例如确定两个重叠像素组合起来是否足够“坚固”以进行碰撞,从而使“模糊”的部分 alpha 位图到处乱飞。此示例不涵盖 alpha,并且适用于 Android,但该示例一般适用:

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

一些附加信息可以在这里找到:

多边形相交的简单算法

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

注意:如果您确实想使用矩形,包括矩形束堆叠成近似形状,作为碰撞的边界,然后(完全公开)我为此制作了一个 jQuery 插件。既然你说你非常依赖 jQuery:

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

The most common solutions to this are either to deconstruct the parts into triangles and then do overlap testing, or to render it as a pixelated bitmap and do pixel-at-a-time comparisons.

The former is called either Tessellation or Triangulating a Polygon:

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

And has the benefit of being better than O(n^2). There are a number of algorithms to do it, mostly because 3-D engines need to generate lists of triangles to hand to graphics accelerator hardware, which often takes information in triplets of [x,y] coordinates.

The latter is unfortunately O(n^2), but allows you to do things like checking the alpha of a bitmap, so that things that are "clear" in a picture (alpha zero or some cutoff) don't count. Thus, you do interesting things like determine if two overlapping pixels combine to be "solid" enough for a collision, and thus have "fuzzy" partial-alpha bitmaps flying around. This example does not cover alpha, and is for android, but the example holds in general:

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

Some additional information can be found here:

A simple algorithm for polygon intersection

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

Note: If you do want to use rectangles, including bunches of rectangles stacked in approximate shapes, as the boundary for collision, then (full disclosure) I made a jQuery plugin for that. Since you said you rely on jQuery a lot:

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

兮子 2024-12-17 14:40:25

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

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

I marked YourPalAl's answer as correct above, but I wanted to leave my final solution as an answer should someone else stumble upon this.

I'm now using jQuery SVG (http://keith-wood.name/svg.html) to insert SVG polygon coordinates as needed which define the boundaries, and checking the objects "next destination" within a 5 pixel tolerance range. If the next destination hits the polygon, I stop the object from moving further.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文