(图书介绍:童晶:《Python趣味创意编程》新书预告)
本章我们将绘制随机山水画,如图所示。首先学习HSB颜色模型,并实现天空颜色渐变的效果;接着利用柏林噪声,实现云朵和山脉的绘制;然后学习随机种子函数,实现鼠标点击更新随机画面;最后学习带参数的函数,改进实现的代码。
10 随机山水画
视频教程:
最终代码:
def setup():
size(800, 600) # 设定画面宽度、高度
colorMode(HSB, 360, 100, 100) # 色相、饱和度、亮度 颜色模型
def draw():
cClouds = color(330, 25, 100) # 云的颜色
cSky = color(220, 50, 50) # 天空的颜色
cFurther = color(230, 25, 90) # 远山的颜色
cCloser = color(210, 70, 10) # 近山的颜色
background(cFurther) # 背景为远山的颜色
drawSky(cSky,cFurther) # 画出天空颜色渐变效果
drawClouds(cClouds) # 画出彩色云朵效果
drawMountains(cFurther,cCloser) # 画出山脉效果
def mousePressed(): # 鼠标按键时
noiseSeed(frameCount*int(random(10))) # 用帧数初始化随机数种子
def drawSky(colSky,colFurther): # 画出天空颜色渐变效果
for y in range(height/2): # 从顶部开始绘制画面上半部分
strokeWeight(1) # 线粗细为1
# 颜色插值,从天空颜色逐渐变成远山颜色
stroke(lerpColor(colSky,colFurther, float(y)/(height/2)))
line(0, y, width, y) # 横着的一条线
def drawClouds(colClouds): # 画出彩色云朵效果
noStroke() # 不绘制线条
for y in range(height/3): # 在上面三分之一部分
for x in range(0,width,2): # 横向遍历
noiseValue = noise(x*0.004,y*0.02) # 柏林噪声
ration = map(y, 0, height/3, 150, 5) # 越向下、云越透明
fill(colClouds, ration*noiseValue) # 设置透明度
circle(x, y, 2) # 画圆
def drawMountains(colFurther,colCloser): # 画出山脉效果
mountainLayer = 8 # 一共画8层山
for n in range(mountainLayer):
# 每一层山的y坐标的最小值
yMin = map(n,0,mountainLayer,height*0.2,height*0.8)
# 山的颜色由远向近渐变
fill(lerpColor(colFurther,colCloser, \
float(n+1)/mountainLayer))
beginShape() # 开始画一些顶点组成的图形
vertex(0, height) # 第一个点在左下角
for x in range(0,width+1,2): # 从左到右遍历
# 柏林噪声
noiseValue = noise(x*0.005,yMin*0.02) \
+ 0.03*noise(x*0.3,yMin*0.2)
# x横坐标对应的高度,越近的山,高度越向下
yMountain = map(noiseValue, 0, 1, yMin, yMin+height/2)
vertex(x, yMountain) # 添加这个点
vertex(width, height) # 最后一个点在右下角
endShape(CLOSE) # 结束画一些顶点组成的封闭图形
生成图片也用在了《C和C++游戏趣味编程》第14章 火柴人的无尽冒险 游戏中,作为不同关卡的随机背景:
对应游戏开发教程可以参看:
https://zhuanlan.zhihu/p/266185523读者也可以尝试修改代码,实现浮云流水的效果:
这一章主要讲解了带参数的函数,学习了HSB颜色模型、随机种子函数等知识,实现了随机山水画。读者也可以利用柏林噪声,尝试实现连绵不绝的随机山水画效果。
有了函数之后,我们可以把程序分成多个简单模块分别实现,更加容易开发出功能复杂的代码。读者也可以尝试把前几章案例中的部分功能用函数封装,进一步理解模块化编程的开发思路。
更多推荐
第10章 随机山水画(《Python趣味创意编程》教学视频)
发布评论