243浏览
查看: 243|回复: 0

Mind+Python turtle 课程——05 模拟3D星空

[复制链接]
本帖最后由 木子呢 于 2021-9-14 16:03 编辑

第五课 模拟3D星空


目录:


功能介绍
经过前面几节课的学习,我们对海龟绘图的不同函数和使用方法都有所了解,包括自定义函数的创建和使用。这节课开始我们的代码相对复杂一点,但是编程原理还是和之前一样的。我们首先将学习turtle库的Screen函数的相关用法,之后在屏幕上模拟出一个3D星空。其中部分代码的使用方法可以查看附录部分内容获取。课程会分为两个任务的形式进行,下表为课程任务及涉及到的知识点。

实现功能
知识点
任务一:绘制屏幕
Turtle库Screen函数
任务二:添加飘动的星星
随机数函数、if语句、while循环


项目实践
任务一:绘制屏幕
1、任务分析
在上节课的学习内容中,我们学会了自定义函数和函数的调用。在这节课,我们将学会新的函数,也就是screen()函数,通过screen()函数的功能绘制出一个屏幕,并设定好屏幕的标题及背景色。

2、编写程序
代码如下:

from turtle import *#导入turtle库中所有工具
screen = Screen()#把Screen()函数赋值给screen,后面都用screen来代表
width,height = 800,600#设定宽度和高度
screen.setup(width,height)#以设定好的宽度和高度来创建屏幕
screen.title("模拟3D星空")#设定屏幕标题
screen.bgpic('浩瀚银河.gif')#添加银河背景图,对应文件一定要有对应的图,否则会报错
screen.delay(0)#这里要设延时为0,否则很卡
done()#用来停止画笔绘制,但绘图窗体不关闭
3、运行效果
运行此段程序,我们可以看到弹出了一个有着炫酷的银河背景的屏幕,而在屏幕的左上方,写有“模拟3D星空”的标题,这正是我们设定的屏幕标题。

1.png
4、代码释义
4.1turtle库Screen()函数的使用

[size=12.0000pt]screen[size=12.0000pt] [size=12.0000pt]=[size=12.0000pt] Screen()[size=12.0000pt]#把Screen()函数赋值给screen,后面都用screen来代表
[size=12.0000pt]width,height[size=12.0000pt] [size=12.0000pt]=[size=12.0000pt] 800,600#设定宽度和高度
screen.setup(width,height)#以设定好的宽度和高度来创建屏幕
screen.title("模拟3D星空")#设定屏幕标题
screen.bgpic('浩瀚银河.gif')#添加银河背景图,注意对应的图片需要放到和程序在同一个文件夹中,否则会报错
screen.delay(0)#这里要设延时为0,否则很卡

4.1.1代码解释
screen是我们新创建的变量,而Screen()是turtle库中的函数。在这里,我们将Screen()函数赋值给screen变量,后面都用screen来表示。当然了你也直接可以使用Screen(),注意字母的大小写。通过Screen()函数,我们使用setup()命令来初始化屏幕,title()命令来设定屏幕的标题,delay()命令来设定延时,bgpic()命令来设定屏幕的背景图片。

4.1.2注意事项
screen.title("模拟3D星空")#设定屏幕标题

Screen()函数下的title()命令可以用来绘制屏幕的标题,这里,我们要在括号内加入一对引号,引号内的内容无论中英文,它都可以原封不动地在屏幕上显示出来。

screen.bgpic('浩瀚银河.gif')#添加银河背景图

Screen()下的bgpic()命令可以用来添加屏幕的背景图,值得注意的是这里的背景图片需要我们事先找好并放入程序所在文件夹中。其中,图片的格式需要是gif的才行,如果找到的是其他格式的图片,我们可以借助电脑自带的画图软件将图片另存为gif格式后再使用(注意这里不能直接修改后缀名,如后缀为jpg的图,直接重命名修改为gif的图时是会报错的)。存放文件的步骤可以参考下列说明:

(1)在文件目录中单机“更多”按钮
2.png


(2)点击“打开文件夹位置”
图片6.png


(3)在弹出的文件夹中放入gif格式的图片,放入图片后即可关闭窗口
图片7.png


(4)回到mind+编程界面,点击刷新按钮
图片8.png

(5)刷新后,即可看到我们插入的gif图,这就完成导图操作了
图片9.png

screen.delay(0)#这里要设延时为0,否则很卡

Screen()下的delay()命令可以用来设定屏幕显示的延时,我们可以尝试删除这行程序,删除后屏幕显示或屏幕内元素的动作有时候会变得较卡顿,因此为了保证流畅性,我们在这里添加延时功能。

任务二:添加飘动的星星
1、任务分析
经过任务一的学习,我们已经绘制了一个银河背景的屏幕,这是一个静态的效果,那如何让我们的星空更加逼真呢?接下来让我们结合随机数函数给星空添加一些飘动的小星星吧。不过在此之前,我们需再次了解画布(屏幕)的坐标设置,比如一个400*300的画布坐标如下图所示

666.png


从上图坐标我们可以看出,如果x坐标值大于200或者x坐标值小于-200时,证明不在画布之内,这个属性是我们程序中需要的,当然了还有其它很多的一些属性。
了解画布的坐标属性,对我们后面理解程序有很大的帮助。首先我们会添加了一个个小星星,之后使小星星向左飘动起来,注意飘动这里我们让它从右边往左边飘动的(当然也可以选择其它方向),飘动的过程如下

图片10.png 图片11.png

我们需要实现以上运动,需分为以下四步

5555.png


第一步:获取星星的初始坐标

如上图所示,当我们需要让小星星从左边飘到右边时,关键点是需要知道它的初始坐标值。首先是从右边飘过来的,所以它的横坐标是确定的一定要大于画布/2的值如上面举例画布为400*300,那么我们的x值一定要大于200,换成任意画布也就是width/2,而纵坐标是从我们可以选择任意坐标都可以(只需在-150到150范围内任意值均可),所以可以用randint(-height/2,height/2)来表示。

第二步:生成星星列表
为了产生很多从右到左运动的星星,我们这里将使用列表。首先需要建立一个空列表,在空列表中我们首先画一个圆代表星星,之后克隆该圆,并设置形状大小。下图为生成的列表。
图片12.png
第三步:实现星星从右到左运动
如上图所以,我们生成星星的坐标值是可以随意的,但是我了确保让星星从右到左的运动,所以这里的x坐标值需要比width/2大。而为了能在画布()中显示,我们的横坐标需要在-height/2和height/2范围内才可以看到。以一个球为例,小球从右到左运动,在y轴坐标不变的情况下,我们只需要改变x轴坐标即可,在这里我们使用星星初始的坐标减去3倍小球的移动速度获得(如果想要星星运动得更快,可以把相应的倍数改大即可)。

图片13.png

第四步:实现循环执行
为了使星空中所有星星能始终保持移动的状态,我们需要使用永久循环结构,
将所有操作包含在内。

图片14.png

对此,我们采用循环结构与分支结构嵌套的方式编写。具体流程如下

图片15.png

2、编写程序
代码如下:

from turtle import *#导入turtle库
from random import random,randint#导入随机数库
screen = Screen()#把Screen()函数赋值给screen,后面都用screen来代表
width ,height = 800,600#设置屏幕宽和高
screen.setup(width,height)#初始化屏幕
screen.title("模拟3D星空")#设置屏幕标题
screen.bgpic('浩瀚银河.gif')#添加银河背景图
screen.delay(0)#这里要设为0,否则很卡
t = Turtle(shape='circle')#绘制圆状星星
t.pencolor("white")#设置画笔颜色
t.fillcolor("white")#设置填充颜色
t.penup()#抬笔
t.setheading(-90)#设置头的方向
t.goto(width/2,randint(-height/2,height/2))#到屏幕右侧随机位置
stars = []#创建星星列表
for s in range(200):#进行200次循环
    star = t.clone()#复制圆
    s =random()/3[size=12.0000pt]#生成一个随机尺寸大小
    star.shapesize(s)[size=12.0000pt]#设定星星的尺寸大小
    star.speed(int(s*10))#移动速度
    star.setx(width/2 + randint(1,width))#设置星星的x坐标在屏幕右侧
    star.sety(randint(-height/2,height/2))#设置星星的y坐标在屏幕范围内
    star.showturtle()#显示星星
    stars.append(star)#扩充星星
while 1:#永久循环
    for star in stars:#循环
        star.setx(star.xcor() - 3 * star.speed())#设定星星的横向移动
        if star.xcor()<-width/2:#判断星星是否移动到了左侧屏幕
            star.hideturtle()#隐藏星星
            star.setx(width/2 + randint(1,width))#设置星星的x坐标在屏幕右侧
            star.sety(randint(-height/2,height/2))#设置星星[size=12.0000pt]的y坐标在屏幕范围内
            star.showturtle()#显示星星
3、运行效果
运行这段程序,我们首先可以看到一个银河系的背景屏,之后一个个小星星从屏幕右侧向左侧飘动起来。

图片16.png
4、代码释义
4.1代码中的算术运算符
算术运算符是计算机用来处理四则运算的符号,基础的运算符有加减乘除等。

4.2代码中随机数函数的使用

from random import random,randint#导入随机数库中的random和randint函数
......
t.goto(width/2,randint(-height/2,height/2))#到屏幕右侧随机位置
......
s =random()/3[size=12.0000pt]#生成一个随机尺寸大小
star.shapesize(s,s)[size=12.0000pt]#设定星星的尺寸大小
......
star.setx(width/2 + randint(1,width))#设置星星的x坐标在屏幕右侧
star.sety(randint(-height/2,height/2))#设置星星的y坐标在屏幕范围内

4.2.1代码释义
在程序的一开始,我们通过from...import”的形式导入随机数库中的random()函数和randint()函数。在这里,随机数库就类似于我们之前学过的turtle库,而“random就是随机数库的库名。之后我们通过randint函数设置星星在屏幕内的随机高度,并利用random函数设置星星的随机尺寸大小。

4.2.2代码中randint()函数的使用
randint()函数的语法格式如下:
randint(low,high)

randint()函数通常用于生成在范围内的随机数,在这里,括号内的low和high分别指范围最大数值和最小数值,其中low为最小的数值而high为最大的数值,这里需注意要将小的值写在前面,例如,我们可以将范围写成(1,10),而不能写成(10,1)。

4.2.3代码中random()函数的使用
random()函数的语法格式如下:
Number = random()

random()函数通常用于无范围的随机数的生成。在这里,Number是一个新建的变量,用来存放我们随机生成的数值。如代码中的s =random()/3,s就是一个变量用来存放我们随机生成的数值。

4.3代码中while循环的使用
[size=12.0000pt]while 1[size=12.0000pt]:[size=12.0000pt]#永久循环

这里我们通过“while 1”的形式来表示永久循环,使得小星星从右往左不停地飘动。

4.3.1什么是循环语句
循环也就是一直重复的做一件事。循环主要有两种类型,第一种是重复一定次数的循环,我们称之为计次循环,如之前学过的for循环。第二种是一直重复,直到条件不满足时才结束的循环,我们称之为条件循环,只要条件成立,这种循环会一直持续下去,比如这里的while循环。

4.3.2while循环使用方法
while 条件表达式:
    循环体

图片17.png
while 循环语句的执行流程图

这里的条件表达式,就是用来判断条件是否成立的语句,条件成立返回数值“1”,表示真,条件不成立返回数值“0”,表示假。比如语句“明天是周六”,如果明天确实是周六,那么条件成立,表达式就会返回数值“1”,表示真。而如果明天不是周六,那么条件就不成立,表达式就会返回数值“0”,表示假。
这里的循环体,就是表达式的返回值为真时要重复执行的操作。而如果要使得循环体语句永久执行,那么只要使表达式返回值始终为真即可,这里我们省略了表达式,直接使用“while 1”来表示永久循环。

我们以现实生活中的例子来理解while循环。在学校,假如我们一节课的时间是40分钟,那么上课铃声打响后,只要时间不到40分钟,我们就一直上课,而一旦不满足情况,时间超过40分钟了,那么我们就会停下来,结束上课的操作,当然了老师拖堂除外。这里的“时间小于40分钟”就是表达式,而“上课”操作就是循环体。

4.4代码中if条件判断语句的使用

[size=12.0000pt]i[size=12.0000pt]f[size=12.0000pt] star.xcor()<-width/2:#判断星星是否移动到了左侧屏幕
    star.hideturtle()#隐藏星星
    star.setx(width/2[size=12.0000pt] [size=12.0000pt]+[size=12.0000pt] randint(1,width))#设置星星的x坐标在屏幕右侧
    star.sety([size=12.0000pt] randint(-height/2,height/2))#设置星星[size=12.0000pt]的y坐标在屏幕范围内
    star.showturtle()[size=12.0000pt]#显示星星

4.4.1代码解释
“if”表示如果,这里我们利用if语句使飘出屏幕的星星能一直不停地出现。如果星星从右侧飘到了左侧屏幕范围之外,那么我们先使星星从屏幕上隐藏起来,之后重新设定星星的x和y坐标并将星星显示出来。

4.4.2什么是if条件判断语句
条件判断与条件循环语句一样,是计算机在解决一个问题时采用的一种方式。在生活中,我们总是要做出许多选择,下面给出几个常见的例子:

1. 如果闹钟响了,我们就起床
2. 如果下课铃声响了,我们就下课
3. 如果输入的用户名和密码正确,则提示登录成功
以上例子中,“如果”后面的内容就是要判断的条件,“则”后面的内容就是满足条件后执行的操作。

4.4.3if语句使用方法
if 表达式:
    语句块

图片18.png
if 语句的执行流程图

这里的表达式就是要进行判断的条件,而语句块则是满足条件后要进行的操作。

项目小结
本节课我们通过turtle库的Screen函数创建了一个以银河系为背景的屏幕,之后借助随机数函数在屏幕中添加了一个个飘动的小星星,模拟出了一个3D的星空效果。通过这个项目,我们进一步熟悉了turtle绘图工具的使用,也学习了随机数函数。同时,我们也了解了while循环语句和if条件判断语句。那么在这节课学习的基础上,结合随机数函数,想一想,我们如何能使小星星随机出现呢

教程中图片下载链接如下,
背景图片下载:
提取码:lxdb


项目扩展
利用本节课学习的随机数函数,结合turtle库dot()函数的用法(可以查看附录进行了解),尝试让小星星在星空中随机出现吧,想一想绘制它需要哪些操作呢。
参考程序
from random import *#导入随机数库
import turtle#导入turtle库
screen = turtle.Screen()#赋值screen对象
width ,height = 800,600#设定宽度和高度
screen.setup(width,height)#以设定好的宽度和高度来创建屏幕
screen.title("模拟3D星空")#设定屏幕标题
screen.bgpic('浩瀚银河.gif')#添加银河背景图
screen.delay(0)#这里要设为0,否则很卡
turtle.speed(0)#设定画笔绘制的速度
for i in range(250):#循环250次
    turtle.penup()#抬笔
    x=randint(-400,400)#设定随机的x坐标
    y=randint(-400,400)#设定随机的y坐标
    turtle.goto(x,y)#将画笔移动到坐标为x,y的位置
    turtle.pendown#移动时绘制图形,缺省时也为绘制
    size=randint(1,10)#随机的尺寸大小
    turtle.dot(size,'white')#绘制具有特定大小和某种颜色的圆点
turtle.exitonclick()#点击退出
参考效果
图片19.png

附件: 5、模拟3D星空.rar (1.18 MB, 下载次数: 15)
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

为本项目制作心愿单
购买心愿单
心愿单 编辑
[[wsData.name]]

硬件清单

  • [[d.name]]
btnicon
我也要做!
点击进入购买页面
上海智位机器人股份有限公司 沪ICP备09038501号-4

© 2013-2021 Comsenz Inc. Powered by Discuz! X3.4 Licensed

mail