为2D游戏生成平滑地形的最简单方法是什么?


23

为2D游戏(例如“月球越野车”或“路线960”)生成平滑地形的最简单方法是什么?

我在stackoverflow.com上得到了有关生成随机高度数组并稍后对其进行模糊处理的答案。是的,还可以。但是最好给出一些点,并获得平滑的曲线。

Answers:


13

一种可以实现以下目的的方法:

  • 在屏幕中间创建一个高度随机的点;您现在有两个部分,在这一点的每一侧
  • 对于每个部分,分为两部分,在该部分的中间放置一个点,其两个相邻点之间的距离(范围为随机)
  • 重复n次。

每次迭代都会使风景中的细节变得更好。

边界情况的处理方式取决于您:例如,可以假设点位于(0,height / 2)和(width,height / 2)。

希望这可以帮助!

编辑:这是我作插图的图片:

地形

这是相同的想法!


12

假设您想要一个实际上平坦的地形,我建议您退后基于噪声的答案,并了解它们的来源。“噪声”信号本质上是无数个振幅随机的正弦波之和,给定频率下的“平均”振幅是频率f的函数。您可以通过这种方式获得大多数常见的“噪声”定义。例如,布朗运动具有1 / f ^ 2频率响应(即,给定频率下的平均幅度与频率的平方成反比):这意味着附近的点之间存在相当大的相关性,因为信号的高频分量很大阻尼。相比之下,经典的分形噪声(中点位移,Perlin噪声等)具有1 / f频率响应。附近的点之间存在更多方差,但仍具有相当大的相关性。更进一步,白噪声具有恒定的频率响应-任何一点之间都没有任何关联。

你这有什么好处?好吧,您只需将少数正弦波求和,但要确保它们在任何给定频率下具有适当的幅度,就可以获得一个看上去有些嘈杂的平滑信号。您希望频率是“随机的”,这样它们中的任何两个都不会有一个共同的倍数(否则,您将获得一个与丘陵总体形状有关的周期性分量),所以我建议采取以下步骤(完成与工作示例):

  1. 在[1..10]范围内随机选择4个(真实)数字-这些将是您的正弦波的频率。我在random.org上掷骰子,得到:f 0 = 1.75,f 1 = 2.96,f 2 = 6.23和f 3 = 8.07。数字4没什么神奇的(您可以使用更多,但是使用更少的数字将开始使单个正弦波更加明显)或此处的1到10的范围(这只是确保最高和最低的一种方法频率不是遥远)。选择一个频率在[1..2]范围内的频率,然后选择另一个频率在[2..10]范围内,以使您拥有一个已知的“主要”正弦波可能是有意义的。
  2. 对于这四个(或多个)频率f i中的每一个,对于某个常数C,-C / f iC / f i之间的某个范围内选择一个振幅a i。您在此处选择的值控制着整个波的振幅-为了方便起见,我选择了C =1。然后,我需要[-1 / 1.75(= -0.571).. 1 / 1.75(= 0.571)范围内的随机数。 ],并且类似地在[-0.338 .. 0.338],[-0.161 .. 0.161]和[-0.124 .. 0.124]范围内。再次四次滚动的骰子,我得到了一个0 = -0.143,一个1 = -0.180,一个一个3 2 = -0.012,和= 0.088。(请注意,这可能不是执行此步骤的最佳方法-因为该函数的最大可能值是振幅abs(a 0)+ abs(a 1)+ abs(a 2)+ abs(a 3),在将它们生成后,将四个a i值中的每一个除以该总和,然后将每个中i值与C相乘,这样可以确保函数可以达到的最大精确度可能更有意义 C ^
  3. 匹克四“偏移” Ø ,每个在范围[0..2π(0..6.28) -这些都将调整你的波的起点,使它们不都在0开始。我得到Ø 0 = 1.73,o 1 = 4.98,o 2 = 3.17和o 3 = 4.63。
  4. '绘制'函数f(x) = a 0 sin(f 0(kx + o 0)+ a 1 sin(f 0(kx + o 1)+ a 2 sin(f 0(kx + o 0)+ a 3 sin(f 0(kx + o 0)-这里= 1,所以我的整体函数是f(x) = -0.143 sin(1.75(x + 1.73))-0.180 sin(2.96(x + 4.98))-0.012 sin(6.23(x ķ是另一个恒定,一个控制你的功能水平“拉伸”。您必须弄清楚这对于您自己的应用程序是什么;为了方便起见,我刚刚选择了k+3.17))+ 0.088 sin(8.07(x +4.63))。

这是我的示例运行的结果,如Wolfram Alpha中所示-请注意,它固定了其图形的大小以用于显示,但是您应该通过我上面提到的常量对结果的水平和垂直范围进行充分控制:

简单随机正弦曲线


10

中点位移算法可以产生美丽的2D地形。

地形示例

中点位移与@tykel的建议之间存在细微的差异。泰克尔(​​Tykel)的算法将视界细分并选择新的高度。这将创建地形,在这些地形中峰均匀分布。人类擅长选择规律性,因此生成的地形看起来似乎是生成的,而不是自然的。

中点的力量来自于选择中点,然后沿该线的法线移动。这将导致峰值上下左右变化。结果地形是分形的,人类将分形视为自然的。

如果再添加几个参数(水平位移,最大坡度等),则随机的高度位移可能会导致地形下降。这突出了MPD的另一个优势。调整非常简单。两个参数,颠簸度和详细程度。


7

您可以使用噪声函数生成随机高度。它们中最简单的是值噪声,其作用与您的描述完全相同:生成一些随机整数高度,然后进行插值在它们之间高度。最常用的插值方法是三次S曲线映射:

假设您的高度h0为point x0,高度h1为point x1。然后,要获取任意点xx0<=x<=x1)的高度,请使用

t = (x-x0)/(x1-x0); // map to [0,1] range
t = t*t*(3 - 2*t); // map to cubic S-shaped curve
h = h0+t*h1;

用这种方法获得的高度将是平滑的,随机的,但并不是很有趣。为了使您的地形更好,可以使用分形噪声。它的工作方式如下:假设您已经生成了一个函数h(x),该函数返回给定坐标处的高度(使用上述方法)。此功能具有一个频率,该频率由原始整数高度的频率确定。为了从中产生分形,可以将具有多个频率的函数组合在一起:

fbm(x)=h(x) + 0.5*h(2*x) + 0.25*h(4*x) + 0.125*h(8*x);

在此示例中,我组合了四个频率-原始频率,两倍,4倍和8倍原始频率,较高的频率赋予了较少的权重。从理论上讲,分形一直延伸到无穷大,但实际上只需要几个术语。的fbm式中的代表分数布朗运动-这是该功能的名称。

这是一项强大的技术。您可以使用倍频器,使用不同频率的权重,或添加一些功能来使噪声失真。例如,要获得更多的“山脊”感觉,h(x)可以将其更改为1-abs(h(x))(假设-1<=h(x)<=1

但是,尽管所有这些都很好,但是该技术存在严重的局限性。使用基于“高度线”的方法,永远不会出现地形“悬垂”。而且我认为它们在类似“月球越野车”的游戏中会是一个非常不错的功能。

添加漂亮的突出部分是一项艰巨的任务。我能想到的一件事-您可以从分形的“高度线”开始,然后将其“细分”为一系列的样条曲线或贝塞尔曲线。然后,地形线将由几个“关键点”定义。对这些关键点施加一些抖动-这将导致地形随机变形,可能会形成一些有趣的形状。但是,这种方法可能会引起地形自相交的问题,特别是在抖动量较高的情况下。


4

有两种流行的方法可以生成地形高度图。

此处给出的一些答案已经基于Diamond-square算法,但是知道名称可以更轻松地搜索更多信息。佩林噪音也有其他用途,因此最好还是进行检查。


OP谈论的是马里奥风格的2D景观,但这些仍然是很好的链接。
tenpn 2011年

1

我的想法是创建一个平滑的噪声函数。首先使用intNoise(int)方法,该方法返回“ random” int,但取决于输入。如果两次使用相同的输入,则结果将相同。

然后使用平滑方法制作一个floatNoise(float),它使用输入周围的两个整数来构建随机值。

然后将X位置用作输入,将Y位置用作输出。结果将是一条平滑的曲线,但高度随机。

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.