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

https://gxnotes.com/article/82289.html

问题描述

为”Moon Buggy”或“路线960”的2D游戏生成平滑地形的最简单的方法是什么?

我在stackoverflow.com得到一个答案,生成一个随机高度的数组,并在后面模糊。是的,这是非常好的。但是最好给出一些要点,并获得一个平滑的曲线。

最佳解决方案

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

  • 在屏幕中间创建一个随机高度的点;你现在有两个部分,一个在这一点的两边

  • 对于每个部分,分为两部分,在本节中间放置一个点,其两个邻居之间的(范围)随机高度

  • 重复n次。

发生什么事情是风景中的细节每次迭代都会变得更细。

如何处理边界案例取决于你:你可以假设(0,height /2)和(width,height /2)的点。

希望这可以帮助!

编辑:这是我为了说明图:

algorithm,procedural-generation,terrain

This is the same idea!

次佳解决方案

midpoint displacement algorithm可以生成美丽的2d地形。

algorithm,procedural-generation,terrain

中点位移与@tykel建议之间有微妙的不同。 Tykel的算法细分了地平线,并选择了一个新的高度。这产生了峰值均匀间隔的地形。人类在挑选规律方面是非常好的,所以生成的地形似乎是生成的,而不是自然的。

中点的力量来自于选择中点,然后沿着该线的法线移位。这样会导致峰值上下变化。所得到的地形是分形的,人类认为分形是自然的。

如果您投入了更多的参数(水平位移,最大坡度等),随机高度位移可能会导致下降的地形。这突出了MPD的另一个优势;调好就很简单两个参数,颠簸和细节水平。

第三种解决方案

假设你想要一个实际平滑的地形,我建议从noise-based的答案中退出,并了解他们来自哪里。 ‘noise’信号本质上是无限多个随机振幅的正弦波的和,其中在给定频率处的’average’振幅由频率f的函数给出。您可以通过这种方式获得大多数常见的’noise’定义。例如,布朗运动具有1 /f^2频率响应(即,给定频率处的平均幅度与频率的平方成反比):这意味着附近的点具有相当的相互位置,因为信号的high-frequency分量是很大的阻尼。相比之下,经典分形噪声(中点位移,珀林噪声等)具有1 /f频率响应;附近点之间有更多的差异,但仍然有相当多的关联。进一步,白噪声具有恒定的频率响应 – 任何点之间根本无相关性。

这对你有什么好处?那么,您可以通过将几个正弦曲线相加来确定它们在任何给定频率下都具有适当的幅度,可以得到一个平滑的信号,仍然有一点嘈杂的感觉。你想要的频率是’random’,所以没有两个它们将有一个共同的倍数(否则你会得到一个周期性的组件到你的山丘的整体形状),所以我建议像以下过程(完成工作例):

  1. 在[1..10]的范围内随机选择4个(实数) – 这些将是您的正弦波的频率。我在random.org上滚动了骰子,得到:f0 = 1.75,f1 = 2.96,f2 = 6.23,f3 = 8.07。没有什么神奇的数字4(你可以使用更多,但使用更少,将开始使个人正弦波更明显)或范围1到10这里(这只是一种确保你的最高和最低的方式频率不是太远)。选择范围[1..2]中的一个频率,其余的在范围[2..10]中可能有意义,以便您具有已知的’dominant’正弦曲线。

  2. 对于这四个(或多个)频率fi中的每一个,在-C /fi和C /fi之间的范围内为某些常数C选择幅度ai。您在此处选择的值控制波的总体幅度 – 为方便起见我选择了C = 1.然后我需要在[-1 /1.75(= -0.571).. 1 /1.75(= 0.571)]范围内的随机数字,类似地在[-0.338 .. 0.338]的范围内, [-0.161 .. 0.161]和[-0.124 .. 0.124]。再次骰子四次,我得到a0 = -0.143,a1 = -0.180,a2 = -0.012,a3 = 0.088。 (请注意,这可能不是完成此步骤的最佳方式 – 由于函数的最大可能值是幅度abs(a0)+ abs(a1)+ abs(a2)+ abs(a3)的和,生成它们之后,您可以将每个四个ai值分配一次,然后将每个值乘以C,以便您可以确定该功能可以获得的精确最大值。

  3. 选择四个’offsets’ oi,每个都在[0..2π](0..6.28)的范围内 – 这些将调整波的起始点,使它们都不是从0开始。我得到o0 = 1.73,o1 = 4.98,o2 = 3.17,o3 = 4.63。

  4. ‘f绘图’函数f(x)= a0 sin(f0(kx + o0))+ a1 sin(f0(kx + o1))+ a2sin(f0(kx + o0))+ a3sin(f0(kx + o0)) – 这里k是另一个常量,它控制着你的函数的水平’伸展’。你必须弄清楚这是你自己的应用程序;为方便起见,我选择了k = 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 + 3.17))+ 0.088sin(8.07(x + 4.63))。

这是我的示例运行的结果,如在Wolfram Alpha中绘制的那样,它注意到它将其图形的大小修正为显示目的,但是您应该通过上述常数对结果的水平和垂直拉伸进行充分的控制:

algorithm,procedural-generation,terrain

第四种方案

您可以使用噪声函数来生成随机高度。其中最简单的是价值噪声,其工作原理与您的描述完全相同:您生成一些随机的整数高度,然后在它们之间插入高度。 most-often使用插值法是立方S-curve映射:

假设在x0点处有高度h0,在x1处有高度h1。然后在任意点获得高度x(x0<=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);

在这个例子中,我组合了四个频率 – 原始,双倍,四倍和八倍的原始频率,较高的频率给出较少的重量。理论上,分形态一直到无穷大,但实际上只需要几个术语。公式中的fbm代表分数布朗运动 – 这是该功能的名称。

这是一个强大的技术。您可以播放带有不同频率权重的倍频器,或添加一些功能来扭曲噪声。例如,要获得更多的”ridged”感觉,h(x)可以更改为1-abs(h(x))(假设-1<=h(x)<=1)

然而,虽然这一切都很好,但这种技术有很大的局限性。以“高度”为基础的方法,你永远不会有地形“悬垂”。而且我想象他们是一个非常好的功能,在一个“月球越野车”般的游戏。

添加漂亮的悬垂是一项艰巨的任务。我可以想到的一件事 – 你可以从分形”heightline”开始,并将”tessellate”变成一系列样条曲线或贝塞尔曲线。那么地形线将由几个”key points”定义。对这些关键点应用一些抖动 – 这将导致地形的随机变形,可能形成一些有趣的形状。然而,地形self-intersections可能会成为这种方法的问题,特别是在抖动量较大的情况下。

第五种方案

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

这里给出的一些答案已经基于Diamond-square算法,但是知道这个名字可以更容易地搜索更多的信息。佩林的噪音也有其他用途,所以检查它是很好的。

参考文献

注:本文内容整合自google/baidu/bing辅助翻译的英文资料结果。如果您对结果不满意,可以加入我们改善翻译效果:gxnotes#qq.com(#替换为@)。

本文由 《共享笔记》整理, 博文地址: https://gxnotes.com/article/82289.html,未经允许,请勿转载。

猜你喜欢

转载自blog.csdn.net/kakaxi2222/article/details/75126275
今日推荐