如何在基于回合,基于距离的策略游戏中确定可能的运动范围?


11

我正在使用c ++和SFML-2.0创建一个二维的,基于回合的策略游戏。运动是基于距离的,而不是基于网格的,具有几个不同的三角形块,这些三角形块在给定的转弯中可以就位旋转或向前移动。

移动将以这样的方式进行:玩家选择棋子要移动到的位置,从而为棋子生成一条可能的路径。玩家确认自己的决定后,棋子将沿着该路径移动到所需位置。路径受到两个因素的限制:距离,一块东西可以走多远,考虑任何转弯(因此,如果有一条曲线,它将是沿着曲线的长度,而不是直接从一点到另一点);和转向角,即在移动(例如,从-30度到30度)时,该零件在任何(以及每个点)可以旋转多远。

我的问题是,我应该如何确定玩家可以选择将棋子移动到的潜在位置范围?

我不确定要在这里使用什么方程式和/或算法。我最初的计划过于复杂,以至于几乎无法实施,更不用说解释了,在这一点上,我因项目停滞而完全迷失了。

考虑到其转弯半径,如何确定设备可以移动的范围?

例如,在下图中。红线,蓝线和绿线的长度都相同。紫色圆圈表示单位可以移动的移动范围。(形状可能不准确,线条的长度实际上可能不相同,但您会明白的)

在此处输入图片说明


它仍然只能移动相同的(总)距离。因此,问题实际上是关于弄清楚“它要旋转多远?” /“它需要旋转多少?” /“ 它需要向哪里旋转?”。您可能需要从确定常规路径开始,然后对大于一定角度的角度后退一步。请注意,直线路径中的最终距离(最晚转弯)将比曲线更长。
Clockwork-Muse

是的,行进距离是主要限制因素。我在这里最大的障碍是,我需要考虑到只要它仍然有可用的距离,它就可以转动并继续转动,直到它可以到达的任何点。
sfphilli

您是什么意思,单位可以移动的范围?您的意思是它可以移动的要点?您对线性代数(向量)有多熟悉?
BlueRaja-Danny Pflughoeft13年

1
您想模拟哪种现实情况?您的问题在需求上过于模糊,导致提出了太多的解决方案。有一种众所周知的方法(实际上)可以解决该领域中的每个具体问题,但是每个人都在猜测您实际上要解决的是许多问题中的哪一个。
Pieter Geerkens

1
我想@PieterGeerkens因为OP不要求代码,所以他们要求算法。并且提供了有关可以合理构思算法的方案的足够详细信息。这是普遍且可以接受的。
MichaelHouse

Answers:


4

使用Dijsktra的生成流场或距离场。

本质上,使用Dijkstra算法填充一个没有目的地的网格(可能是一个不同的名称;不知道)。只需获取每个开放节点,计算可到达的邻居,将其推入开放列表,在封闭列表中进行设置,适当地更新父节点的“下一条”路径,等等。在确定到达新节点的成本时,请考虑转向限制。

现在的结果是,您拥有一个由所有节点组成的网络,以了解如何重新开始。第一步不会触及无法到达的节点。计算得出可以到达的节点将具有“沿最佳父路径的下一个节点”元素,因此您既可以突出显示所有节点,又可以在用户悬停或单击突出显示的区域时使用此信息显示或执行移动路径。


我不怎么解释这个概念,也不知道我如何实现它,但是肯定是正确的方法。
Pieter Geerkens

我对算法的理解是节点遍历必须与路径无关。因此,为了完成此任务,您需要添加另一个专用于面对的自由度(在另一个轴上创建节点)。换句话说,对于每个不同的X,Y(可能是Z)和Facing的组合,您将有一个节点。否则,找到进入节点的最短路径不会在离开节点时区分不同的面。那是对的吗?如果是这样,这种方法是否可能过于密集?
TASagent

@TASagent:好点,我认为完全没有做到这一点。然后,该算法可能会有些不足,但是该方法应该可行。
肖恩·米德迪奇

@PieterGeerkens:我同意这是一个错误的解释。您应该做出自己的答案,以更好地说明一切。
肖恩·米德迪奇

这似乎很接近我的需求,但是我不得不承认我从未听说过那种算法,因此不知道如何将其推广到我的需求。您是否碰巧有指向任何良好信息或教程的链接?
sfphilli

4

暴力解决方案是:

  1. 在单元周围创建一个顶点圆,以单元为中心。圆的半径是最大移动距离。顶点的密度可以根据最终结果的详细程度而变化。
  2. 对于每个顶点位置,模拟单元转向该位置的运动。这是在没有渲染的情况下紧密循环完成的。
  3. 在转向模拟中达到最大距离时,将顶点移至模拟单元的点。该点是单位在当前转向结束之前最接近该顶点的位置。这具有将圆缩小到实际运动大小的效果。
  4. 使用这些顶点以及以单元为中心的顶点来创建渲染的圆以绘制可能的移动距离。

在此处输入图片说明

因此,从蓝色圆圈开始,您将处理路径,最后以紫色圆圈结束。然后,您可以将这些点与设备上的中心点配合使用,以显示形状所需的红色三角形。(仅制作该图像就使我意识到该形状是不正确的,但是看到真正正确的形状会很有趣)


3

我将在一个单独的答案中扩展Sean的解决方案,因为它代表了与我最初提出的方法不同的方法。

该解决方案可能代表了最易用的方法。它需要将您的环境划分为多个节点。是的,这是重新引入基于网格的方法,但是可以使其相对精细,或用于在节点内处理更精细定位的广泛路径查找。节点结构越粗糙,寻路速度越快。

这里最大的问题是您实际上是在面对船只,因此许多传统的寻路解决方案都必须经过修改才能使用。这些通常与路径无关,因为它们并不关心您如何到达所在的节点。当加速,减速和转弯是即时且自由的时,这种方法就很好用。不幸的是,转弯不是免费的。但是,由于在这种简化中确实丢失了一条额外的信息,因此我们可以将其编码为另一个变量。在物理学中,这称为相空间。

现在假设二维,您可以推断出3:

通常,每个允许的离散坐标位置需要一个节点。例如:

(0,0) - (1,0) - (2,0)
  | \  /  |  \  / |
(0,1) - (1,1) - (2,1)

等等,您将构造一个相邻点的节点图,并通过空间邻接关系将它们连接起来。然后,您将使用Dijkstra的算法,杀死超过转弯允许移动值的节点,直到没有未探索的,活着的节点与探索的节点保持连接。每个节点都跟踪达到该节点所需的最小距离。

为了将此方法扩展为可与Rotation一起使用,请在3维中想象这个相同的节点图。Z方向对应于旋转/朝向,并且是周期性的,这意味着如果您继续沿+ Z方向行驶,则会回到起点。现在,仅在与该方向相对应的面之间连接与相邻位置相对应的节点。您可以照常遍历连接到已探索节点的节点。我建议在此方案中限制为N,NE,E,SE,S,SW,W,NW。

该解决方案可以告诉您所有可到达的空间区域,以及到达该位置的最佳路径,到达该位置时的旋转角度以及到达该位置时的所有方向。

然后,在实际执行路径时,您可以随意插值/三次样条曲线,使其看起来更加真实。


1
太好了 我需要对算法进行一些研究,然后在游戏中进行实验,但这确实使我感到非常满意,特别是因为我可以将其推广到游戏的其他重要部分。
sfphilli

1

听起来您可能需要首先决定您想要怎样才能随时随地工作。选项如下:

  • 如果它们在圆锥体内移动,请先旋转,然后再开始移动。这是易于实现和解决的方法。它也不太有趣,所以我不想使用它。

  • 移动时连续转动,最高可达45度。这是一个棘手的问题,希望您会喜欢。使用固定的时间步长对路径进行数字积分可能是最简单的方法。圆锥体将受到最大(每步+ X度)和最小(每步-X度)旋转的限制。

这些要求中的第二个如何最好地穿越太空,很大程度上取决于它们将要进入​​的环境。如果您必须穿越许多障碍,那么事情可能会变得非常棘手且非常昂贵。但是,如果没有,则可以预先加载(甚至逐渐减小)旋转,以最终到达所需的位置。

我觉得我可能只部分涵盖了您有疑问的主题,因此随时在评论中添加更多内容,可以扩大讨论范围。


我绝对想使用第二个选项,即沿路径的任意点(可能是每个点)都旋转(例如)45度。还会有障碍物,每个障碍物都大于碎片(请考虑巨石)。我最初考虑的方式是生成一个可能的端点的圆锥体,然后为这些端点中的每个端点生成一个新的圆锥体,依此类推,直到每个可能的位置都达到最大移动距离。就是说,我不确定如何在没有疯狂的过度复杂的情况下实现这一目标。
sfphilli

嗯,似乎我/有些细节不清楚。回顾这个问题,我看到您指定了“基于转弯”的功能,并且这些单元可以在转弯时“旋转或移动”。那么,这是否意味着玩家要提前许多回合来计划他们的动作,而您想在他们移动时进行寻路?关于运动应该如何工作的进一步澄清将是有帮助的。
TASagent

不,我的意思是,在给定的回合中,玩家可以将棋子旋转到位,但可以随心所欲地旋转多远,也可以按照已经看过的方向移动。如果它们移动,则它们可以沿着路径走一段特定的距离,并且可以在移动时转向或转向特定角度(例如,从-45到45度的任何角度)。因此,假设选择的路径将包含一条曲线以便向左或向右移动。路径将由玩家在我无法确定的可能点的范围内选择他们想要移动的点来确定。
sfphilli

好的,实际上,这听起来很不幸,对于我们上面讨论的Dijkstra算法,您想要的特性可能太过严格了:-\。可能吧 到家后,我会为此画一些东西。
TASagent

您可能需要编辑一些收集到的信息,以将问题澄清为原始问题,以便以后的人们可以从更多信息开始。
TASagent
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.