用于计算目标最大子弹路径的算法。2 ricochets


21

对不起,标题很抱歉,但我没有更好的措辞...

因此,任天堂在Wii上开发了一款名为WiiPlay的出色游戏(是!)。里面有9个迷你游戏,而我最喜欢的一个叫做《坦克》!。这是关于销毁COM敌方坦克而又不致使自己遭到破坏的事情。这是一个关卡的屏幕截图:

在此处输入图片说明

摧毁坦克的一种方法是发射子弹。有一个石灰绿色的敌方坦克,可以发射高速子弹,两次弹跳(对着墙壁和方块)。您会看到,如果玩家的坦克停在现在的位置,如何立即将其摧毁,因为位于中央的石灰坦克可以按照我在图像上绘制的绿色路径发射子弹。

作为一名业余程序员,我一直想知道石灰罐如何确定朝哪个方向射击以击打玩家罐。

我自己考虑过,但是没有提出任何可能的算法。如果他们启发了某人,我将解释我的结论。为了简单起见,我假设一堵墙是子弹可以弹到的任何表面。因此,一个孤立的矩形块形成了四个墙。

我得出的结论是,子弹跳线始终位于平行四边形的一侧或变成平行四边形的相反顶点的两个点。它瞄准的射击敌方坦克和玩家坦克不一定是其他两个顶点,而是肯定位于与平行四边形的四个边中的任何一个共线的直线上。这是形成平行四边形的4种可能方式的说明:

在此处输入图片说明

HOR-VER意味着子弹首先撞击水平的墙壁,然后撞击垂直的墙壁。

然后我被卡住了。我曾考虑过绕一条连接敌方坦克和玩家坦克的地图绕线移动,以查看它是否与任何墙面的任何两个击打形成平行四边形,但这并不总是可行的,因为敌方坦克和玩家坦克不是必须与平行四边形的顶点重合。

另外,我不确定算法的一般流程。该算法是否采用以下两种结构中的任何一种,或者我对这两种结构都错了?

  • 不断找出可能的路径,并始终将其标记为最佳路径(可以是最短,最模糊,最不可避免的路径,或者是基于多个标准的组合加权评估),而忽略了其余的路径。毕竟,剩下的一个是最好的选择。
  • 首先确定首先由子弹到达的所有墙壁(子弹不需要弹跳到任何其他墙壁即可到达这些墙壁中的每一个),然后确定这些墙壁中的每个墙壁上的所有可到达范围(有时不可能到达目标上的遥远点)如果您附近还有一堵墙,则没有弹跳的墙),然后再次确定所有带有弹跳的可到达​​墙,以及在这些墙上可到达的所有范围。这4个过程可以通过类似于光线跟踪的方法来完成。在每个过程中,如果玩家的坦克被任何射线击中,请根据该射线找出子弹路径。

我认为该算法很难弄清楚,原因是:

  • 子弹可以向任何方向发射;和
  • 在数学上,每堵墙上都有无数个点,在线上有无数个点。

但是任天堂的人还是成功了,所以...有人有主意吗?


只是为了检查一下,您要问的是如何做到这一点,而不是任天堂选择如何实际做到,对吗?
Ixrec 2015年

@lxrec是正确的,只是对一种可能的方式感兴趣,而不是他们的方式感兴趣。
你好

游戏不需要找到解决方案。当您按下按钮开火时,游戏已经知道您面对的位置和方向,那么它仅使用该信息。它将追踪轨迹,如果在路径中找到敌方坦克,您将击中它,否则将其击中。
Mandrill

2
尽管存在“无限”的多个角度,但您可以轻松地将它们简化为几个等效类。尼基·凯斯(Nicky Case)的“ 视觉与光”是演示多边形之间阴影的一个很酷的演示-这确实是您的问题,除了您使用的是子弹路径而不是光线,并且光线可能会反射两次。请注意,反射对AI并不重要-反射仅延伸了视线,尽管这确实意味着可以从多个角度看到同一物体。
阿蒙(Amon)2015年

@Mandrill恐怕您还不太明白我的问题。我在问敌人的坦克如何设计出击中玩家坦克的子弹路径。
你好

Answers:


9

从直接的角度来看,这个问题显然是微不足道的。但是,我们正在处理反思。在将反射实现为光线跟踪器的一部分时,正确找出场景的哪些部分是一项挑战,因为这可能会错过一些开口。在两个有希望的角度之间进行“二进制搜索”也是不可行的:由于反射,实际可见的空间不是连续的,因此启发式“如果位于A的右侧和B的左侧,则必须有一个目标A和B之间的解决方案”是不允许的,并且会错过“创意”解决方案。我反而建议实施重新运行从虚拟位置追踪反射-我们的坦克射击的位置似乎是在照镜子看到:

target |obstacle
   X   |
    \  |  X real position
     \   /
      \ /
   ----------- mirror surface
        \
         \
          X virtual position

优点在于,镜射光线现在是源自虚拟位置的直线。我尝试在以下草图中说明该技术:

转角射击

X表示射击位置,X表示目标。彩色区域可见。

  1. 直视:目标不可见。但是,我们可以击中表面(1)和(2)。

  2. 一思。障碍物内有两个虚拟射击位置。较低的位置使LOS直射到目标,因此我们有第一个发射解决方案:子弹路径是目标与下镜面之间以及射线与镜子碰撞点与实际发射位置之间的射线部分。

  3. 两次反射:第一次反射的上方虚拟位置可以通过其镜面看到下部障碍物的一部分。由于允许两次反射,因此我们可以将此位置镜像到下部障碍物。这些位置标记为(I)实际位置,(II)第一次反射的虚拟位置,和(III)二次反射的虚拟位置。

    从(III),我们将LOS瞄准了目标(X),因此我们找到了另一种射击方法。子弹路径沿着线X–III直到第二个镜面碰撞点,然后沿着镜面碰撞点之间的线III–II,最后沿着线II–I从第一个镜面碰撞点到实际位置I。

    实际上,第一次反射的下虚拟位置也可以反射到上障碍物,但这不会导致任何直接解决方案。

一旦确定了障碍物的哪些部分是可见的(因此可以用来反射子弹),通过深度优先搜索实现镜像就很简单了。为了找到合适的镜面,可以使用Nicky Case的Sight&Light中概述的技术:不是尝试360个矢量(可能会错过开口,而且很浪费),而是仅向障碍物边缘发射光线。


我不了解“仅在障碍物的边缘发射光线”的工作原理。您是要开始向墙壁的末端发射光线,然后逐渐向内发射直到找到解决方案?如果是这样,我了解使用此规则可以更快地找到解决方案。
您好

经过一番考虑,我认为这是最好的答案,因为显然,按照我之前标记为最佳的数学答案,不能直接处理一跳和无跳的解决方案。
您好

这太棒了!关于如何在不对游戏要求太高的情况下如何创建关卡的镜像表示的任何建议?
retrovius18年

7

只是将Karl Bielefeldt的想法扩展为2面墙反射:在此处输入图片说明

给定A和B(水箱)。首先,您必须列出A可以看到的所有墙壁以及B可以看到的所有墙壁的列表。然后进行配对,其中第一堵墙在拳头列表中,第二堵墙与第一堵墙不同,并且在第二堵列表中。您需要针对所有可能的墙对进行此测试(除非您找到消除候选人的方法)。找到给定墙对的R和S后,您将进行检查

1)如果A具有R的直接视野

2)如果R属于wall1(wall只是一个线段,没有整条线)

3)如果R可以直接访问S

4)如果S属于wall2(wall只是一个段,没有整条线)

5)如果S可以直接访问B。

查找R和S:由于您知道wall1,因此可以确定与wall1相切的线方程,由于R属于与wall 1相切的线,因此R的2个坐标之间有一个关系(以1个自由度表示) R)与S相似(由于该点属于wall2的线切线,因此在S坐标之间具有关系)。因此,现在您有2个自由度,并且必须有2个其他独立方程式才能确定解。一个方程是:

(AA')/(RA')=(SS')/(RS')

另一个等式是:

(BB')/(SB')=(RR')/(SR')

请注意,在上面的方程式A,A',B,B'是已知的或可以直接计算的。R'和S'是R和S坐标以及墙方程的函数。我没有完成数学运算,所以不知道方程式如何。


这是一种很棒的数学方法。但是我猜该算法需要很多计算时间才能求解联立方程式?距离涉及很多平方根和幂运算。
您好

3

您可以利用一个事实,即离开跳弹的角度必须与进入它的角度相同。对于具有给定水平壁y坐标c和两个固定槽具有坐标(a,b)(d,e),仅存在一个角度,其满足下面的公式。

方程图

只需解决x沿您必须瞄准的墙壁的距离即可。两堵墙的工作原理相同。您只有两个方程式和两个未知数。


1

您有显示如何引导光线的整洁图表,因此我将保留有关如何确定一对反射面的详细信息。

让我们叫,必须先出手面的面一个,第二个,

尝试通过向A射击击中B的(可见)边缘。换句话说,确定其中一个会看到的端部的反射点如果着眼于镜面。这必须很容易做到,您只需要处理一个反射点。

现在您知道了两条光线照射到B的(可见)边缘。我们称它们为边缘射线计算它们在B处的反射他们必须超越目标。您可以确定目标是否位于它们之间,即一条射线的左侧,但在另一条射线的右侧,反之亦然。使用直线一般公式做到这一点是微不足道的。

如果目标不在边缘射线之间,则显然无法用任何中间射线击中目标;选择另一对表面。

如果目标光线之间,寻找使用二进制搜索中间击球射线。您有两个与边缘射线相对应的发射角,您的命中角位于它们之间。从发射点看,如果目标的角直径不太小,那么您只需进行几次迭代,直到找到照射光线的方向即可。

这是一张图片:

射线

此处,两条边缘光线以红色和蓝色显示。显然,您会发现发出的射线的角度小于红色的射线,但大于红色的射线,因此该射线会撞击绿色目标。


不,不一定!考虑一下您的图,如果红色和蓝色子弹路径之间的任何地方都存在一个额外的障碍。如果您以红色和蓝色角度之间的某个角度发射子弹,您可能会受到更近的击中,但您也可能会完全错过,因为有些子弹可能会弹开介于两者之间的随机障碍物。请参阅@amon的答案,其中他讨论了这种可能性。
您好

赞成@amon的答案;我喜欢直线镜像的想法。我还假设该算法在以这种简化的方式找到击中路径后,应该检查击打路径是否确实可以通过。如果目标仅被部分遮挡(可能甚至分成两个可见区域),则可能会更加有趣。阿蒙的方法更适合处理它。
9000

-3

首先,还记得物理课上谈论光的折射吗?使用这些原则可以解决您的问题。入射角等于反射角。因此,敌方坦克需要在所有可能的角度下进行第一次弹跳,以便第二弹跳可以击中玩家。继续遵循射线追踪的想法。现在,当玩家移动时,这变得很复杂,但这对于您开始使用算法来说应该是一个足够好的主意


1
我了解反思的原则。您可以看到我对@amon评论的回复。没错,必须考虑玩家的移动,但我认为可以将其作为在评估的基础上从多个可能路径中选择一个最佳路径的一项标准。但是,这可以忽略不计,因为这与子弹路径的距离有关,,路径越长,玩家在子弹到达目的地之前可以移动的越多。
你好
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.