【问题标题】:How to randomly place objects as player move around in an infinity map without overlap?当玩家在无限地图中移动时如何随机放置对象而不重叠?
【发布时间】:2015-11-20 13:30:17
【问题描述】:

我试图制作一个游戏,其中玩家只能在无限地图中向前移动,并且路径(就像点一样,路径只是视觉效果)是程序生成的。我希望这些路径具有不同的长度(something like the tree of life,但只生成所选路径的分支)。


这就是我如何生成没有重叠的分支:

List<Vector3> everyPos; //predetermined position

public void Spawn(int amount)
{
    List<Vector3> possiblePos = new List<Vector3>(everyPos);

    for (int i = 0; i < amount; i++)
    {
        int index = Random(0, possiblePos.Count);          //Find a random position
        SpawnObjectAt(currentPosition+possiblePos[index]));//Create a point there
        possiblePos.RemoveAt(index);                       //Remove that position from the list
    }
}

问题是,look at this image(I can't embed image yet):

红色是玩家开始的地方,绿色可能是第一步的生成位置。

如果在1和2产生了2个点,玩家选择point1,那么第二次可能的位置将是黑色区域中的一个点,其中包括point2,所以如果我继续下去,最终会重叠.


我怎样才能避免这种情况?我正在制作一个手机游戏,所以我不想缓存每一个点。任何帮助将非常感激!谢谢!

这是一个小型网页游戏,其机制与我试图实现的目标有些相似:newgrounds.com/portal/view/592325/

【问题讨论】:

  • 您使用什么语言?您能否包含一些代码或一些图像来解释您的意思?
  • 我用的是C#但是任何语言都可以,其实我不需要任何代码,只是一个方向。关于图片我在上面添加了一张图片,以及一个简单的游戏,只需一分钟即可尝试
  • 我玩过这个游戏,但我不明白你所说的路径重叠是什么意思,但如果你想生成一个“喜欢”的路径,应该不会太难。

标签: c# mobile random procedural-generation


【解决方案1】:

这里试图回答,但老实说,您需要提供更多信息。

根据您所使用的语言,您可以采用不同的方式进行处理。您可能需要动态分配,但现在让我们假设,因为您的想法非常小,您可以在编译时执行一个预定义的大数组。

我假设你知道如何创建一个数组,所以创建一个长度为 500 的数组开始。如果你想像他们在那个游戏中那样“生成”一个链接,你只需要一个随机函数,(我认为几乎每种语言都有一个内置库),你需要做一些数学运算。

无论您使用哪种语言,都肯定有内置的图形库,或者您可以使用流行的易于使用的图形库。我只是画一张图来说明这一点。

您可以通过多种方式在数学上做到这一点,如图所示,例如使用角度,但是最简单的方法就是按照框。

如果您以前使用过图形,您就会知道什么是矢量,如果没有,您将需要学习。该图像中呈现的 9 个向量 (0,1) (1,0) (1,1) 等可以创建为向量对象,甚至可以存储为单独的整数。

要使您的节点“移动”到另一条路径,您可以简单地执行 rand 1-9,然后将结果与 9 个可能的向量之一相关联,然后将它们添加到您的位置向量。在数组中执行此操作最简单,只需使用 rand int 作为索引。在大多数 c 派生语言中,您会这样做:

positionVector += changeVectorArray[rand(1,9)];

然后,您将位置向量增加 9 个向量之一,如上所示。

制作“路径”的最简单方法是在添加更改向量之前复制位置,然后将所有更改顺序存储在另一个“路径”数组中。

要在屏幕上显示路径,只需在路径数组的第一个和第二个、第二个和第三个、第三个和第四个元素之间画一条线。如果我没记错的话,这个(连接线的)公式是离散数学,如果你愿意,你可以做更复杂的路径形状,但你明白了要点。

这至少应该让你开始。如果没有更多信息,我真的无法为您提供帮助。

我可以直截了当地描述一堆不同的方法,你可以用不同的方式实现这一点,但如果你只是询问细节,它可能更容易。

编辑>>>

继续这个答案,是的,现在看,节点肯定可以重叠。要解决此问题,您可以使用碰撞检测,每次生成新的“位置”时,在添加它并绘制线之前,您必须像这样循环遍历数组:

boolean copy = true;
for(int i = 0; i < getLength(pathArray); i++){

     if( newVector == pathArray[i]){
        copy=false;
     }
}

那么当然,如果复制仍然为真,则将新位置复制到 pathArray 中。注意:整个解决方案非常草率,并且随着数组变大,您的程序将花费越来越长的时间来搜索该循环。这可能也不能保证路径朝一个方向行进,但很有可能。请注意,即使位置向量不能相互重叠,这些线仍然可以相互重叠。

考虑到所有这些,我认为它会起作用,优化取决于您。我建议使用离散公式可能有一个更有效的解决方案。您还可以使用这样的公式使路径朝着特定的方向前进并执行其他更复杂的事情。

如果您想让路径朝着特定方向前进,您也可以很容易地对随机滚动应用约束。但是有很多方法可以做到这一点,我无法开始解释。你可以用谷歌搜索路径查找算法。

祝你好运。

【讨论】:

  • 感谢您的回答,我更新了我的问题。关于碰撞检测,我认为这不是一个好主意,它就像通过暴力破解密码一样。我相信一定有更好的方法来做到这一点。
  • 没问题。您可以通过单击绿色对勾来接受答案。
  • 解决重叠问题的一种简单方法是将随机滚动限制为 (+1,0) (0,+1) 或 (+1, +1) - 这意味着它只能正确,向上或直立。使用这些约束,不应该有任何重叠。
  • 据我所知,唯一的其他方法是碰撞检测或寻路。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-09-23
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-06-13
  • 1970-01-01
相关资源
最近更新 更多