查找导弹和位图地形的交点的最有效方法是什么?


10

在回答了我先前关于查找2D位图地形的坡度的问题后我现在需要了解在导弹上击中的2D地形上找到点的最佳方法。显然,我可以看到导弹下方是否有任何像素与地形相交,但是可以说它已经深入到地形中。

返回到最初碰撞位置的最佳方法是什么?我可以一次将X像素移回导弹的先前位置,但是X的一个好值是多少?还有更聪明的方法吗?也许移动一半的距离,然后移动四分之一,等等?


您所描述的现象通常称为“隧道效应”,解决该现象的最佳方法是引入扫描测试-正如TetraD和JasonD在下面都提到的那样。
jpaver

只是说“扫描测试”实际上并没有帮助我。如何在位图地形上做到这一点?
伊恩

杰森的建议对我来说似乎是最好的:一次只能一个像素。
jpaver

Answers:


3

对于碰撞测试,您不应进行逐笔的静态测试,而应进行跟踪/扫描测试。

这里有针对不同类型的基元的各种公式的详尽列表:http : //www.realtimerendering.com/intersections.html

也就是说,当然,假设您可以将地形分解为可以测试的某种图元集(即线段)。有多种方法可以做到这一点。

另请参见以下问题(仅略相关):检测运动球体之间碰撞的良好算法是什么?


我正在考虑像《蠕虫》中那样的可破坏位图地形。您可以从位图动态生成图元吗,还是太疯狂了?
伊恩

1
我敢肯定您可以,但是仅对任意位图进行逐像素测试可能会更容易/更快。
Tetrad

四重奏!! (这样就不会永远结束)
bobobobo

3

如果您的风景不多且弹丸快速移动,二进制搜索将无济于事-您可能会错过它们。

我认为您最好的选择是沿着炮弹的前部沿着它所经过的路径扫一条线,一次像素。您可以先对整个体积进行边界检查,以避免每一步都进行边界检查。


什么是二进制搜索?
伊恩

1
抱歉-二进制搜索或多或少是您在问题中所说的。您从中间开始,然后将搜索空间除以2,直到收敛到答案为止。在许多情况下,它是最佳选择,但在您的情况下,它是行不通的(您可能会完全跳过正确的答案)。
JasonD

3

由于导弹不太可能每帧移动大量像素(在屏幕上不会很平滑),所以我认为没有理由不仅仅检查路径上的每个像素。Bressenham线算法是您的朋友,并确保您也获得了位图的本地副本,因为您通常不希望每个像素都访问视频内存。这是假设您的位图地形是完全随机的(根据可破坏的蠕虫地形)。如果您的世界是基于图块的,则可以跳过所有您知道是空的图块,但是如上所述,除非您要检查的导弹数量巨大,否则我无法想到一个平台,该平台太慢了只需逐个像素地进行测试,就不需要在原始类型中定义您的世界(蠕虫的克隆将使这一过程变得棘手)


是的,我当时在想蠕虫般的地形。您能否将其动态划分为图块,然后将空白图块标记为不检查?如果一次有很多导弹,也许会加快速度吗?
伊恩

那么,您认为我应该逐像素向前移动,检查相交,而不是向后退吗?
伊恩

我认为所有三个答案都建议进行正向搜索。如果向前的步骤使其跳过某些场景,则向后检查将不起作用。
JasonD

是的,肯定会向前。
Kaj 2010年

1

除了其他答案外,如果您想做一些记账工作,例如将一堆像素“收集”到“已知相似状态”的块中,可以采取一些措施来加快速度。例如,您可以存储最高地形的高度,因此可以认为,只要导弹高于该高度,导弹就不会击中任何东西。您还可以存储最低“空中”空间的高度,因此您将知道,如果导弹到达该高度,则它一定已经命中了某些物体(尽管最好将其用作健全性检查)。不仅如此,您可以存储代表所有地形的矩形和其他全部为空气的矩形,但这可能比价值更大。

最终,最好的方法可能是“保留每个地形列的高度”,然后仅在其路径的每一步计算导弹高度。我无法谈论更多现代游戏,但我相信当您在焦土中制作“洞穴”时,该洞穴上方的地形会直线下降,没有悬垂之处。如果您想突出工作,那么工作会更大一些,但这将是此基本思想的扩展。(提示:首先使基本想法起作用!)

由于您的地形可能是完全任意的,因此没有捷径可走。即使您强迫地形成为样条曲线或类似的东西,一旦开始销毁它也会感到不高兴,并且样条线交点测试是反复的,不完美的或详尽的,并且对于您的问题类型而言毫无意义地缓慢。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.