检查以下gif:https://i.gyazo.com/72998b8e2e3174193a6a2956de2ed008.gif
我想让圆柱体在圆柱体上放置立方体后立即将位置更改为平面上最近的空白区域。立方体和圆柱体附有盒子对撞机。
当我在上面放一个立方体时,气缸刚刚卡住了,我必须向某个方向点击以使其开始"游泳"通过立方体。
是否有任何简单的解决方案,或者我是否必须使用空标记对象创建某种网格,这些标记会告诉我它们上是否有对象?
答案 0 :(得分:2)
这是类似RTS的视频游戏中的常见问题,我自己也在解决它。这需要breadth-first search算法,这意味着您首先要检查最近的邻居。您很幸运,只需要在网格环境中解决此问题。
程序员通常会做的是创建一个队列,并将整个游戏中的每个节点(空间)添加到该队列,直到找到空白空间。它将从例如上面,下面和起始空间的相邻空间,然后递归地移出,在自身内部调用相同的函数并使用队列来跟踪仍然需要检查的空间。它还需要有一种方法来了解是否已经检查过一个空格并避开这些空格。
我设想的另一个解决方案是从起点生成(概念)Archimedean spiral并以某种方式检查该螺旋上的每个空间。棘手的部分是产生正确的螺旋,并在恰当的点检查它,以便击中每个空间一次。
这是我在c ++中对阿基米德螺旋方法的快速解决方案:
float x, z, max = 150.0f;
vector<pair<float, float>> spiral;
//Generate the spiral vector (run this code once and store the spiral).
for (float n = 0.0f; n < max; n += (max + 1.0f - n) * 0.0001f)
{
x = cos(n) * n * 0.05f;
z = sin(n) * n * 0.05f;
//Change 1.0f to 0.5f for half-sized spaces.
//fmod is float modulus (remainder).
x = x - fmod(x, 1.0f);
z = z - fmod(z, 1.0f);
pair<float, float> currentPoint = make_pair(x, z);
//Make sure this pair isn't at (0.0f, 0.0f) and that it's not already in the spiral.
if ((x != 0.0f || z != 0.0f) && find(spiral.begin(), spiral.end(), currentPoint) == spiral.end())
{
spiral.push_back(currentPoint);
}
}
//Loop through the results (run this code per usage of the spiral).
for (unsigned int n = 0U; n < spiral.size(); ++n)
{
//Draw or test the spiral.
}
它生成一个可以按顺序迭代的唯一点矢量(浮子对),这将允许您以漂亮的向外(宽度优先)网格螺旋绘制或测试起始空间周围的每个空间。使用1.0f大小的空间,它会生成一个由174个测试点组成的圆圈,并且在0.5f大小的空间中,它会生成一个包含676个测试点的圆圈。您只需要生成一次螺旋,然后将其存储在程序的其余部分中多次使用。
注意:强>
n += (max + 1.0f - n) * 0.0001f
)。我将这个解决方案用于我正在进行的游戏中。 More on that here.以下是一些图片(第一张图中的橙色线条是我在Paint中绘制的,为了说明,第二张图片只是为了演示如果展开螺旋线的样子):