关于工具介绍这里小生就不赘述了,这里附上个人觉得最详细的文档地址:https://docs.python.org/zh-cn/3/library/turtle.html?highlight=turtle#turtle.TurtleScreen
先看效果图:
以上就是小生牺牲午休时间捣鼓出来的~虽然不是辣么好看,但是还是想跟大伙分享一下,进入正题。
代码主要分为两部分:树代码部分,地上花瓣部分
树代码部分
其实代码很简单,主要是我们得知道如何去实现那些关键点(我知道这是废话,但是我总得说点什么凑字数...):
1,树干应该是越往上越细 - 即画笔越往上 size 尺寸越小
2,枝干越往上越短 - 枝干延伸的长度
3,枝干会分叉 - 即递归事件继续执行的入口
4,枝干分叉的角度 - 画笔偏移度
4,要长点什么 - 递归事件的出口
满足了以上几点,这棵树看起来才会正常一点(或者说符合大众观念)。总的来说,我们需要一个点来决定递归事件
的入口和出口,这里我用分叉次数来决定,当然还可以用延伸长度等或一个变量,只要我们能找到出入条件,看代码:
1 # 画树方法: n为枝干延伸次数,l为枝干延伸长度 2 def drawTree(n, l): 3 pendown() 4 # 设置画笔颜色 - 枝干颜色 5 pencolor('#5d3c3c') 6 # 画笔尺寸 7 pensize( n / 1.5) 8 # 延伸长度 9 forward(l) 10 # 根据 n 判断是否继续递归延伸枝干 或 结束本分支延伸 11 if n > 0: 12 # dr 为画笔顺时针偏移度,dl 为画笔逆时针偏移度 13 dr = randint(30, 40) 14 dl = randint(30, 40) 15 16 # 本次延伸长度:每一次随机减少延伸长度(所以也可以根据 l 来设置 pensize等) 17 move = l * (random() * 0.4 + 0.5) 18 19 # 顺时针偏移 dr 20 right(dr) 21 # 递归调用自身,剩余延伸次数 -1 22 drawTree(n - 1, move) 23 # 因为上面顺时针偏移了 dr,所以顺时针的偏移度加上逆时针偏移度:dr + dl 才是分叉实际偏移度 24 left(dr + dl) 25 drawTree(n - 1, move) 26 # 顺时针偏移dl,回到画笔原指向 27 right(dl) 28 else: 29 # 本分支延伸结束,调用画花朵方法 30 drawPetal(3) 31 # 提起画笔 32 penup() 33 # 回到开始延伸的位置 34 backward(l)
花朵代码:
枝干完成指定分叉次数后,为了好看一点,即需要长点什么,如代码:
1 # 花朵绘画方法: n 为花朵半径(其实就是圆半径...) 2 def drawPetal(n): 3 # 指定颜色模式为 rgb 模式 4 colormode(255) 5 # 随机生成 rgb 色值 6 r = randint(200, 255) 7 g = randint(8, 158) 8 b = randint(8, 158) 9 10 # 画圆并填充颜色 11 begin_fill() 12 fillcolor(r, g, b) 13 pencolor(r, g, b) 14 circle(n) 15 end_fill()
到这里如果只是为了画一棵树,那我们的工作已经基本完成了,当然我们需要一个启动方法:
def run(): # 设置画布比例: 相对显示屏 setup(1.0, 1.0) penup() # 移动到坐标 (-50, -150) goto(-50, -150) # 逆时针旋转90度,使画笔指向正上方 left(90) pendown() # 隐藏画笔 hideturtle() # 是否追踪绘画过程:即是否一步一步显示绘画过程 tracer(False) # 调用树方法 drawTree(13, 150)
将上诉代码复制到编辑器里,在调用 run()方法,一棵树神奇的树就会出现了(假设你已经安装了python运行环境)。
让我们再给它洒上一些花瓣,这里花瓣的位置小生将它放在树起始点下方,其实你完全可以随意指定位置和范围以及大小
来展示一张飘落的效果(我已经看过了,很好看):
1 # 花瓣位置生成: m 为花瓣数量,x y 决定绘画花瓣初始位置 2 # 这里我将花瓣初始位置设置为树起点位置附近 3 def petalPlace(m, x, y): 4 penup() 5 goto(x, y) 6 pendown() 7 setheading(0) 8 tracer(False) 9 for i in range(m): 10 # 起始点画一朵 11 if i == 0: 12 drawPetal(5) 13 else: 14 penup() 15 goto(x, y) 16 # a 为下一朵花瓣水平方向相对起始点距离 17 a = randint(20, 400) 18 # b 为下一朵花瓣垂直方向相对起始点距离 19 b = randint(-50, 50) 20 21 # 将画笔移动相应距离 22 forward(a) 23 left(90) 24 forward(b) 25 right(90) 26 pendown() 27 28 # 调用花瓣绘画方法 29 drawPetal(5)
到这里我们的所有代码已经完成,下面是所有代码(已去掉注释):
1 from turtle import * 2 from random import * 3 4 # 画树方法 5 def drawTree(n, l): 6 pendown() 7 pencolor('#5d3c3c') 8 pensize( n / 1.5) 9 forward(l) 10 if n > 0: 11 dr = randint(30, 40) 12 dl = randint(30, 40) 13 move = l * (random() * 0.4 + 0.5) 14 right(dr) 15 drawTree(n - 1, move) 16 left(dr + dl) 17 drawTree(n - 1, move) 18 right(dl) 19 else: 20 drawPetal(3) 21 penup() 22 backward(l) 23 24 # 花瓣位置生成 25 def petalPlace(m, x, y): 26 penup() 27 goto(x, y) 28 pendown() 29 setheading(0) 30 tracer(False) 31 for i in range(m): 32 if i == 0: 33 drawPetal(5) 34 else: 35 penup() 36 goto(x, y) 37 a = randint(20, 400) 38 b = randint(-50, 50) 39 forward(a) 40 left(90) 41 forward(b) 42 right(90) 43 pendown() 44 drawPetal(5) 45 46 # 花朵绘画方法 47 def drawPetal(n): 48 colormode(255) 49 r = randint(200, 255) 50 g = randint(8, 158) 51 b = randint(8, 158) 52 begin_fill() 53 fillcolor(r, g, b) 54 pencolor(r, g, b) 55 circle(n) 56 end_fill() 57 58 # 启动方法 59 def run(): 60 setup(1.0, 1.0) 61 penup() 62 goto(-50, -150) 63 left(90) 64 pendown() 65 hideturtle() 66 tracer(False) 67 drawTree(13, 150) 68 petalPlace(160, -100, -150) 69 70 run() 71 done()
值得注意的是,因为我们使用了很多随机生成的值,所以每一次生成的树都一样,也就是你说,我们可以造一片森林,
有了上面的代码,我们需要补充的已经很少了:
大致思路就是随机生成树的起始点,再调用我们上面的方法就可以了,当然为了美观,部分数值是需要细调的,
最起码每棵树下面的花瓣这个方法不需要了,我们可以换成给整个区域的树加上花瓣飘落效果,这里给个森林例子
(没有改花瓣):
1 # m 对应生成树的数量 2 def run(m): 3 setup(1.0, 1.0) 4 for i in range(m): 5 penup() 6 x = randint(-500, 500) 7 y = randint(-300, 300) 8 goto(x ,y) 9 left(90) 10 tracer(False) 11 drawTree(10, 150) 12 petalPlace(100, x, y)