Python 随机山脉算法(2020年9月12日)


制作背景

大二刚开学不久,和一个朋友Rutubet比赛了一个二维移动的程序设计,其中用到了一种生成地形的算法,同时看到Rutubte分享了一篇有关生成立体山脉有关的算法,受到了启发,于是用python的turtle内置库做了一个一维的生成山脉的展示。

此篇文章为当时参考的 生成立体山脉的思路 https://gameinstitute.qq.com/community/detail/109402 (侵删)

效果截图

n级山脉表示循环执行add函数n次,n越高表示山脉的曲折点数量越多。

低级并且更陡峭

继续调高的效果

可以调高山脉的陡峭程度

3级山脉,可以看出褶皱很少

7级山脉

9级山脉,基本看不出和7级的区别了

低级并且陡峭

源代码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
# -*- encoding: utf-8 -*-
"""
一维山脉生成
2020年9月12日
by littlefean
"""
import turtle as t
from random import uniform


def add(array):
"""
输入一个子元素全为浮点数的数组array,此函数在array内部每两个元素间插入一个数值,
此数值为左右两侧数字的平均值加上正负一定范围内的随机数
用以提高数组所表示的山脉的褶皱数量即复杂程度
并将修改后的数组返回
:param array: 修改前的数组
:return: 修改后的数组
"""
divNum = 1 / (len(array) - 1) / 2
newArray = []
lenNewArray = len(array) * 2 - 1
index = 0
for i in range(lenNewArray):
if i % 2 == 0:
newArray.append(array[index])
index += 1
else:
left = array[index - 1]
right = array[index]
point = (left + right) / 2 + uniform(-1, 1) * divNum
newArray.append(point)
return newArray


def show(array):
"""
传入表示山脉的array数组,并通过turtle绘图将其绘制在屏幕上
:param array: 表示山脉的array数组
:return: 无返回值
"""
R = 450
H = 330
xStart = -R
xStep = 2 * R / (len(array) - 1)
t.penup()
t.goto(xStart, array[0])
t.fillcolor('brown')
t.begin_fill()
t.pendown()
for i in range(1, len(array)):
xStart += xStep
t.goto(xStart, array[i]*H)
print(xStart, array[i]*H)
t.right(90)
t.fd(H)
t.right(90)
t.fd(2*R)
t.right(90)
t.fd(H)
t.end_fill()
t.mainloop()


if __name__ == '__main__':
arr = [0.0, uniform(-1, 1), 0.0]
print(arr)
for n in range(7):
arr = add(arr)
print(arr)
show(arr)

总结

此算法生成的山脉的形状让我想到了很多二维游戏里的场景,比如:百战天虫、泰拉瑞亚、弹弹堂。

这种生成山脉的算法还算比较简单,之前做过二维山脉,用俯视图生成一张位图,但是没能成功,有bug,今后可能会继续挑战一下二维的山脉