代码之家  ›  专栏  ›  技术社区  ›  Peter Jaric

我怎样才能创造一个“无限”的世界?

  •  29
  • Peter Jaric  · 技术社区  · 15 年前

    我想创造一个无限的(实际上是一个非常大的)世界,玩家可以在其中移动游戏。我是否会有时间来实现这个游戏是一个问题,但我觉得这个想法很有趣,并希望一些投入如何做到这一点。

    关键是要有一个这样的世界:所有数据都是按需随机生成的,但都是以一种不同的方式生成的 是的。

    目前,我专注于一个大的二维地图,从它应该可以显示任何部分,而不知道周围的部分。

    我已经通过编写一个函数实现了一个原型,该函数给出了一个随机的,但确定性的整数,给定了地图上像素的x和y(参见 my recent question about this function

    不管怎样,那是 想法,但我相信已经有办法做到这一点,我也相信,鉴于规范,你们中的许多人可以提出更好的想法。

    忘了我问题的链接。

    我想我必须澄清的是,地图的两个相邻部分,分别生成,需要平滑地相互连接,这一点很重要。

    编辑3: 在评论中要求提供更多的信息。

    这是一张照片 from a page about fractal and Perlin Noise 这看起来很像我以前制作的(因为我最好的尝试可能是使用柏林噪音):

    我想做的是从非常大的世界(在MAXINT*MAXINT像素范围内)中选取任何矩形并生成它。如果我要生成上面图像的任何部分,它应该得到完全相同的像素,就像我生成了一个较大的部分包围较小的一个。

    要求的性能 :我的主要目标是基于回合的RPG,所以性能可能会很低,但我想看看是否有可能创建一个快速算法会非常有趣。

    :最好不预生成任何内容,但除此之外,内存使用情况应与任何普通游戏或应用程序匹配。

    要求的详细信息 :好吧,如果你看这张图片,你就知道了。这将是非常好的,虽然,如果有可能缩小和平移,而不必计算地图在最放大的水平第一。

    需要生成的对象类型和对象属性 :没什么特别的,根据上图我对地形很满意。但我承认我一直在考虑一个类似的设置,那里的一切都是一个非常非常大的城市。不过,这将是另一个问题。

    编辑4: 希望是最后一个。

    好吧,读了一点之后,似乎柏林噪音是最好的选择。我还有一个问题(如果有人愿意回答,现在我已经接受了一个(实际上是两个)答案:))。

    5 回复  |  直到 6 年前
        1
  •  5
  •   Unreason    15 年前

    通常,所有地形/世界生成器都按照您描述的方式工作—它们能够从非常有限的输入数据(一组参数)生成大量(随机的)世界。

    所以,你可能想对你的问题做进一步的限制。

    如果有什么对你有用,或者你只是在乞求研究——看看不同的关注点和方法 here .

    再看一看 procedural generation (尤其是“请参阅”和“外部链接”)。

    terrain synthesis 在这里,你基本上混合和匹配真实的地形样本与某种变换操作-这提供了真实的期待地形所需的属性。

    编辑 这里有一个 implementation 中的“等离子体分形”(中点位移) processing .

    如果这对您来说足够好,那么您可以修改算法以允许它生成网格的任何部分(我有一种感觉,它将归结为散列坐标以获得连接线周围或任何地方的随机数种子)。

    此外,您还可以使用此方法处理不同层次的细节,以便生成更接近视点的细节。

        2
  •  2
  •   kasperjj    15 年前

    看看柏林噪声,它是一种确定性随机数据,以它的发明者肯·柏林命名。如果你搜索“柏林噪音”或“肯柏林”,你会发现大量的文章程序纹理和景观生成。

        3
  •  2
  •   PauliL    15 年前

    一种简单的方法是等离子云算法,也称为 Midpoint displacement algorithm . 总体思路是:

    1. 为该区域的角设置一些高度值。
    2. 将矩形分成4个较小的矩形。
    3. 计算新点的海拔高度作为周围点的平均值,并在其上添加一些随机位移值
    4. 递归地将每个矩形划分为更小的矩形,并相应地减少置换量。

    随机值由伪随机数生成器生成。如果您在开始时给出特定的种子,则始终会生成相同的数字序列。

    等离子云提供了相当逼真的景观,但从长远来看,它们变得枯燥乏味。因此,还可以使用更复杂的算法(Perlin噪声、脊Perlin等)。要获得更多的变化,可以使用一个分形(分辨率较低)来调整另一个分形的参数,以计算实际值。

    使用分形和其他程序方法生成景观的程序的一个很好的例子是 Terragen . Terragen生成照片级真实感图像,因此速度很慢,但它有OpenGL预览,可以动态创建景观。

    编辑: 这是因为它通常使用随机数生成器,它依赖于以前的随机数值。

    但是,您并不需要真正统计上良好的随机数生成器来生成地形。 类似这样的(未经测试):

    const int a = 0x7fffffff / 48271;
    const int b = 0x7fffffff % 48271;
    
    int displacement(int x, int y)
    {
        int     seed, result;
    
        seed = x ^ ((y << 1) & 0x2AAAAAAA) ^ ((y >> 1) & 0x33333333);
        result = 48271 * (seed % a) - b * (seed / a);
    
        Return (result & 0xffff);
    }
    

    上述是从实际的随机数发生器修改,使种子是从x和y计算。但也许更简单的函数就足够了。

    编辑2 :创建 无限世界 然后开始用等离子云算法分割正方形。 你只需要分割和计算那些你感兴趣的方块,这样你就能很快到达目标区域(这很像二进制搜索)。

        4
  •  1
  •   Skizz    15 年前

    你得到的几乎是唯一的方法-基本上你已经创建了一个函数,f,它给出了f(x,y)的地理数据。当然,您可以使用几个函数来构建地形。

        5
  •  0
  •   andand    15 年前

    上面有一些文件 here.

    你提到了柏林噪声,而且效果很好,特别是当你需要生成拓扑上不等同于平面的地形时。

    The Science of Fractal Images 有一个关于光谱合成的部分,可以让你根据所需的分形维数调整结果。问题是很难在平面或圆环体上生成其他地形。