我正在用体素地形编写类似mincraft的游戏。
对于山脉,我指定位置,高度和大小。如果当前(x,y,z)坐标处的块是山的一部分,则有一个函数返回True。如果一个区块远离山的中心,则只有当z坐标低于距山的距离的最大高度时,才返回True,即距离山块越远,最大高度越低。因此,在山的中心,最大高度很高,即使z很高,我也会返回True(我正在使用z-up系统)。但是,离山越远,最大高度就越低。
然而,我当前的函数(下面)线性地返回它们,而真正的山峰没有直边:
def isMountain(self, x, y, z, mountainPos, mountainSize, mountainHeight):
if math.hypot(mountainPos[0] - x, mountainPos[1] - y) < mountainSize:
if z < (mountainHeight - math.hypot(mountainPos[0] - x, mountainPos[1] - y)):
return True
else:
return False
第3行检查z是否小于该位置的最大高度,如果是,则返回True,否则返回False。
这些是距离的最大高度:
距离:最大高度
0 - 10
1 - 9
2 - 8
...
9 - 1
10 - 0
如何重新编写此函数以使其返回更多类似山的值:不是线性的,而是立方体或平滑的衰减(如混合器比例编辑模式),因此它会给出更像这样的值:
0 - 10
1 - 9
2 - 9
3 - 8
4 - 7
5 - 5
6 - 3
7 - 1
答案 0 :(得分:1)
你可以试着找出一些数学公式,或者你可以模拟自然侵蚀过程。 这通常使用网格(矩阵,单元格,...)和迭代来完成。 基本上你会从或多或少随机的高地形开始,然后侵蚀它直到形成山脉,实际上山脉仍然存在。 也就是说,这通常比使用简单的功能更昂贵,但在现代计算机上这可以很好地工作。
答案 1 :(得分:1)
如果您对另一条路线感兴趣,可以使用修改后的perlin噪声版本来使用振幅和频率,然后使用平滑过渡来获得您想要的效果。您可以将点设置为具有一般高度范围,然后让噪声算法完成它以在点之间创建可变性。我已经做了一些类似的事情来创建一个具有不同生物群系的inf世界,这些生物群落具有不同的山峰高度和形状。
答案 2 :(得分:0)
也许您可以使用像这样的反正切函数
https://www.desmos.com/calculator/sn7tbepuxh
其中h是最大高度,s是陡度,x是距峰中心的距离。末尾的-1可以忽略负值,从而使山峰的底部不会永远延伸。
我将它用于小型游戏的山峰生成器,并且看起来很不错,只要您将陡度和高度值调整到山峰就不会太尖锐。