我怎样才能产生一个“无限”的世界?

时间:2010-06-16 08:54:10

标签: algorithm random map

我想创造一个游戏,其中包含无尽的(实际上是一个非常大的)世界,玩家可以在其中移动。我是否会绕过实现游戏是一回事,但我发现这个想法很有意思,并且想要了解如何做到这一点。

重点是拥有一个所有数据按需随机生成的世界,但采用确定性方式。

目前我专注于一个大型的2D地图,从中可以显示任何部分,而不需要了解周围的部分。

我已经通过编写一个函数来实现原型,该函数给出了一个随机的但确定的整数,给定了地图上像素的x和y(参见my recent question about this function)。使用此功能,我使用“随机”值填充地图,然后使用基于周围像素的简单过滤器平滑地图。这使得地图依赖于其边缘之外的几个像素,但这不是一个大问题。最终的结果是至少看起来像地图(特别是具有良好的高度颜色图)。鉴于此,人们可能首先生成一个较粗糙的地图,用于产生更大的海拔差异,以创建山脉和海洋。

无论如何,那是我的想法,但我确信已经有办法做到这一点,我也相信,鉴于规范,你们中的许多人都可以提出更好的想法。

修改 忘记了我的问题的链接。

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

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

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

http://www.neilblevins.com/cg_education/fractal_noise/perlin_fractal_max_levels2.jpg

将黑色像素视为深海,将白色像素视为山顶。这就是我需要的,一个简单的2D高程图。

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

现在谈谈Unreason的问题:

所需的性能:我的主要目标是基于回合制的RPG,因此性能可能非常低,但我认为看看是否可以创建快速算法会非常有趣。

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

必需的细节:好吧,如果你看一下图片,你就明白了。如果可以缩小和平移而不必首先在最放大的水平上计算地图,那将是非常好的。

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

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

好的,看了一下之后,似乎Perlin Noise就是这样。我还有一个问题(如果现在有人关心回答我接受了一个(实际上是两个)答案:))。

perlin噪音功能需要两倍。这些双打的范围是多少? [0-1 [?或者我可以高兴地发送我的大整数吗?

5 个答案:

答案 0 :(得分:5)

通常情况下,所有地形/世界生成器都按照您描述的方式工作 - 它们能够从非常有限的输入数据(参数集)中生成大量(随机查看)世界。

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

如果有什么对您有用或者您只是在乞求研究 - 请查看不同的重点和方法here

至于随机性/确定性,我不确定你真的在这里谈论随机性,它可能有点令人困惑,我想你只想创造很多变化。因此,您可能希望从搜索字词中删除它。

另请参阅procedural generation(尤其是“另见”和“外部链接”)。

就我个人而言,我认为terrain synthesis的概念有许多前景,你基本上可以将真实的地形样本与某种变换操作混合搭配,从而提供具有所需属性的逼真地形。

修改: 这是implementation中的processing'等离子体分形'(中点位移)。

如果这对您来说足够好,那么您可以重新编写算法以允许它生成网格的任何部分(我感觉它会归结为散列坐标以获得连接线周围的随机数种子,或者无处不在)。

此外,您可以使用此方法处理不同级别的细节,以便您可以在更接近视角的位置生成更多细节。

答案 1 :(得分:2)

看看Perlin Noise,它是一种以它的发明者Ken Perlin命名的确定性随机数据。如果您搜索“Perlin Noise”或“Ken Perlin”,您会发现大量关于程序纹理和景观生成的文章。

答案 2 :(得分:2)

地形通常是用分形生成的。

一种简单的方法是等离子云算法,也称为Midpoint displacement algorithm。一般的想法是:

  1. 为区域的角设置一些高度值。
  2. 将矩形划分为4个较小的矩形。
  3. 计算新点的高度作为周围点的平均值,并为该
  4. 添加一些随机位移值
  5. 递归地将每个矩形划分为更小的矩形,并相应地减少位移量。
  6. 使用伪随机数生成器生成随机值。如果您在开头提供特定种子,则始终生成相同的数字序列。

    等离子云自动生成平滑过渡,因此无需额外的平滑过滤器。

    等离子云提供了非常逼真的景观,但它们在长期内变得无聊。因此,可以另外使用更复杂的算法(Perlin Noise,Ridged Perlin等)。为了获得更多变化,您可以使用一个分形(低分辨率)来调整计算实际值的另一个分形的参数。

    分形也可用于创建纹理和凹凸贴图。

    使用分形和其他程序方法生成景观的程序的一个很好的例子是Terragen。 Terragen生成逼真的图像,因此它很慢,但它具有OpenGL预览,可以即时创建景观。

    编辑:等离子云的问题在于,如果不生成整个区域,则无法生成单个点(或小区域)。 这是因为它通常使用随机数生成器,它取决于先前的随机数值。

    但是,您并不需要统计上好的随机数生成器来生成地形。 因此,您可以使用某些函数替换rand函数,该函数从X和Y坐标而不是先前的值计算随机数。 像这样(未经测试):

    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计算种子。但也许甚至一些更简单的功能就足够了。

    Edit2 :要创建无限世界,您可以使用10km x 10km的矩形开始。使用上面的置换函数设置目标位置所在矩形角的初始高度。 然后开始用等离子云算法分割正方形。 您只需要拆分并计算您感兴趣的方块,这样您就可以快速到达目标区域(这很像二进制搜索)。

答案 3 :(得分:1)

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

除了Perlin Noise,查找分形景观生成。这些可以产生一些非常自然的徘徊地形。

答案 4 :(得分:0)

有些论文列于here.

你提到过Perlin Noise,效果很好,特别是如果你需要生成拓扑上不等于平面的地形。

The Science of Fractal Images有一个关于光谱合成的部分,可让您根据所需的分形维度调整结果。这个问题是很难在飞机或圆环上产生其他地形。