你知道,在我的世界里,世界在不断扩大,所有的生物群落都是随机的?
我的广义问题是:相对于空间模拟,随着玩家在世界上的移动,空间模拟也在不断扩展,人们将如何用Java编写这种随机化程序呢?
我真正的问题是:我能不能把一个简化的例子分解成这些示例类:
这将是非常有帮助的,目前,因为我想做一个简化的版本这样一个程序。
发布于 2013-06-28 10:48:44
我的经验之谈
“我的世界”中的生物群落并不是直接确定的;生物群落是根据当地的温度和湿度选择的(例如,一个炎热干燥的生物群落最终变成沙漠,一个湿热的生物群落最终变成热带雨林,整个图表见http://www.minecraftwiki.net/wiki/File:BiomesGraph.png 注意:这个图表已经过时了,但是这个概念仍然是最新的。)。
现在你可以随意选择温度和湿度,但这会导致每个街区都有一个不同的生物群落(真的很愚蠢),或者你仍然可以随意选择,但规模更大;这会导致可怕的锋利边缘和生物群落,不应该相邻。例如,沙漠可能在北极冻土带旁边(仍然相当愚蠢)。
天真的解决方案,即不要这样做
解决这一问题的方法是停止随机选择温湿度,而是开始随机选择温湿度变化。起初,这看起来很不错,但因为玩家可以在任何庄园里穿行世界,当世界回到自己的位置上时,你就会遇到问题;你会得到令人讨厌的加入。即使你创造了规则,比如世界是从源头向外创造的,不管走的方向如何,你仍然必须使世界的一部分还没有被玩家探索。即向北走100米,然后向东走10 000米,然后向南走200米。突然之间,你需要“其他10000米东”,你没有走下来想出新的街区将是什么样的。
Perlin噪声(及其更有效的近邻单纯形噪声)
Perlin噪声将位置协调作为输入(以及主种子),并输出一个介于-1和+1之间的值,该值是随机的,并且随着协调的变化而缓慢变化。它通过在几个长度尺度上采样随机数来实现这一点。例如,点(1100,0)将采样:
(1088,0)-16 (四舍五入)
(1120,0)+16 (四舍五入)
(1096,0)-8 (四舍五入)
(1012,0)+8 (四舍五入)
..。
(1100,0)+0
(例如)在+-16水平上,采样点被移动到可被16整除的最接近的值,所以(1100,0) (1101,0) (1102,0)和类似的样本(1088,0)将作为它们的-16点。
并将它们相加,权重将决定价值的变化有多快,对大尺度的高权重会造成缓慢的波动,对于小尺度的高权重会产生更多锯齿状的快速变化值。
它旁边的一个点(1101,0)将采样相同的较高电平点,但最低电平点将不同,因此它的变化只是缓慢的(较高点的权重也会发生变化)。(1109,0)将只有非常高的水平点在共同。
这意味着,要计算(1100,0),您不需要知道任何其他点,您可以在何时生成它们,它们将“最终”逐渐改变。
请注意,单纯形噪声比perlin噪声快得多,在几种更技术性的方法上也更好;然而,数学要复杂得多(给出名字就很有趣)。
结论
如果您只想要真正的随机性(即看起来是静态的),只需使用java的内置随机函数即可。如果您想要随机但缓慢变化的噪声(例如,看起来像山),使用Perlin或单纯形噪声。Perlin和Simplex噪声适用于任何维数,但perlin噪声对于高维数的效率很低,而单纯形噪声随着维数的增加而缓慢增长。
参考文献:
佩林噪声的解释
perlin噪声的Java实现
https://softwareengineering.stackexchange.com/questions/202992
复制相似问题