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

Mind+Python turtle 课程——07 小海龟抓鱼

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

第七课 小海龟抓鱼


功能介绍

通过上节课程的学习我们学会了通过鼠标去控制海龟的移动,学到的知识点包括布尔类型、条件判断、逻辑判断和鼠标控制函数的使用。这节课我们将通过键盘去控制箭头(鱼)的移动,之后设定让鱼在指定范围内游动,而海龟会尾随进行抓捕动作,最终实现海龟抓鱼的效果。课程会分为三个任务的形式进行,下表为课程任务及涉及到的知识点。

实现功能
知识点
任务一:键盘控制鱼移动
键盘控制函数的使用
任务规划区域让海龟在指定区域移动
全局变量、多重if判断条件语句的使用
任务完成海龟追鱼功能
布尔变量、while循环和if语句的嵌套使用

项目实践

任务一:键盘控制鱼移

1、任务分析
在上节课的学习内容中,我们学会了使用鼠标控制小海龟的移动方向,并实现了海龟走迷宫的小游戏。这节课我们学习另一个外设的使用方法,也就是使用键盘来实现控制的功能。首先我们会自定义往前、往后、右转和左转的函数及相应的运动方式。之后通过监听键盘中的按钮是否被按下,如果被按下就只想相应的函数。

2、编写程序
代码如下:

from turtle import Screen, Turtle#导入相应的库
t = Turtle() #赋值对象给t
t.shape("classic")#库函数的默认形状有“arrow”、“turtle”、“circle”、“square”、“triangle”或者“classic”,一般默认为“classic”也就是箭头形状
t.color("red")#设置箭头的颜色
t.penup()#抬笔,行动轨迹不留痕迹
#往前
def up():
  t.forward(10)
#往后
def back():
  t.backward(10)
#右转
def right():
  t.setheading(t.heading() + 10)#每次触发函数,转动方向加10
#左转
def left():
  t.setheading(t.heading() - 10)#每次触发函数,转动方向减10
screen = Screen()#赋值对象给screen
screen.listen() #监听
#输入按键,触发对应的函数
screen.onkeypress(up,"Up")      #按动方向键Up则执行函数up
screen.onkeypress(left,"Left")   #按动方向键Left则执行函数left
screen.onkeypress(right,"Right")  #按动方向键Right则执行函数right
screen.onkeypress(back,"Down")    #按动方向键Down则执行函数back
#点击屏幕退出
screen.exitonclick()

3、运行效果
运行程序可以看到有红色箭头(鱼)的停留在弹窗中,通过键盘上的前后左右可以控制箭头(鱼)进行运动。

图片1.png

4、代码释义


4.1键盘控制函数的使用

screen = Screen()#赋值对象给screen
screen.listen() #监听
#输入按键,触发对应的函数
screen.onkeypress(up,"Up")      #按动方向键Up则执行函数up
screen.onkeypress(left,"Left")   #按动方向键Left则执行函数left
screen.onkeypress(right,"Right") #按动方向键Right则执行函数right
screen.onkeypress(back,"Down")    #按动方向键Down则执行函数back
#点击屏幕退出
screen.exitonclick()

4.1.1代码解释
Screen库也已经非常强大,很多内置函数我们都直接可以使用,这里我们用到了Screen库函数内的listten()函数,即可时时刻刻的监听所有键盘按键是否被触发。这里程序中我们只需监听方向键盘是否有按下,如果按下就执行相应函数的控制内容即可。

图片2.png

4.1.2使用方法
示例程序中我们使用的是方向键控制海龟,如果我们后面还需要有键盘去控制或者制作好玩的游戏,那么我们的这些函数是必不可少的。当然了我们还可以改为其它按键去控制,如使用键盘上的“w”“a”“d”“s”来控制,其它代码不变的情况下,只需要如下修改即可

screen.onkeypress(up,"w")      #按动方向键Up则执行函数up
screen.onkeypress(left,"a")   #按动方向键Left则执行函数left
screen.onkeypress(right,"d") #按动方向键Right则执行函数right
screen.onkeypress(back,"s")    #按动方向键Down则执行函数back

任务二:让小鱼在指定范围内移动

1、任务分析
任务一我们可以让箭头在弹窗内任意位置走动,但有的时候会出画布之外,为了避免这个现象,我们给它设定一个范围,这里我们设置了一个边长为600的正方形,也就是任意坐标的值的绝对值都不得超过300

图片3.png

如果任意移动时小鱼所在的坐标值的绝对值大小范围超出了300的数值,那么就把超出范围的数值设为300。如此前小鱼移动到坐标为(400,200)的位置,但是在显示时会自动变成坐标为(300200)的位置,这样小鱼就无法跑出去了。

2、编写程序
代码如下:
from turtle import Screen, Turtle#导入screen和turtle库
import random#导入随机函数库
boxsize=300#设置一个坐标值为300的盒子
f = Turtle()#赋值turtle给f
f.pensize(5)#设置小鱼的大小尺寸
f.shape("classic")#库函数的默认形状有“arrow”、“turtle”、“circle”、“square”、“triangle”或者“classic”,一般默认为“classic”
f.color("red")#设置小鱼的颜色为红色
f.penup()#提笔
#往前
def up():
  f.forward(10)
  checkbound()#调用检测鱼是否越界函数
#往后
def back():
  f.backward(10)
  checkbound()#调用检测鱼是否越界函数
#右转
def right():
  f.setheading(f.heading() + 10)
#左转
def left():
  f.setheading(f.heading() - 10)
#检测鱼是否跑过界
def checkbound():#自定义checkbound()
    global boxsize#定义全局变量boxsize
    if f.xcor()>boxsize:#检测当前的x坐标是否大于设定的boxsize
        f.goto(boxsize,f.ycor())  #如果大于boxsize,就把x的值设为boxsize,y坐标值不变
    if f.xcor()<-boxsize:#检测当前的x坐标是否小于-boxsize
        f.goto(-boxsize,f.ycor())#如果小于,就把x的值设为-boxsize,y坐标值不变
    if f.ycor()>boxsize:#检测当前的y坐标是否大于设定的boxsize
        f.goto(f.xcor(),boxsize)#如果大于boxsize,就把y的值设为boxsize,x坐标值不变
    if f.ycor()<-boxsize:#检测当前的y坐标是否小于-boxsize
        f.goto(f.xcor(),-boxsize)#如果小于,就把y的值设为-boxsize,x坐标值不变
screen = Screen()
screen.listen()
#输入按键,触发对应的函数
screen.onkeypress(up,"Up")      #按动方向键Up则执行函数up
screen.onkeypress(left,"Left")
screen.onkeypress(right,"Right")
screen.onkeypress(back,"Down")
#点击屏幕退出
screen.exitonclick()

3、运行效果
运行程序,还是用键盘方向键去控制小鱼的移动,此时发现,小鱼会在一定的范围内可以移动。

图片4.png


4、代码释义


4.1代码中全局变量global使用

global boxsize#定义全局变量boxsize

4.1.1代码解释
定义全局变量boxsize,不管是内部还是外部函数都可调用。

4.1.2全局变量和局部变量
变量分为局部与全局,局部变量又可称之为内部变量。由某对象或某个函数所创建的变量通常都是局部变量,只能被内部引用,而无法被其它对象或函数引用。
全局变量既可以是某对象函数创建,也可以是在本程序任何地方创建。全局变量是可以被本程序所有对象或函数引用。

4.1.3使用方法
global语句的使用方法很简单,基本格式是:关键字global,后跟一个或多个变量名,如global xglobal x,y

4.2代码中多重if语句的使用

    if f.xcor()>boxsize:#检测当前的x坐标是否大于设定的boxsize
        f.goto(boxsize,f.ycor())  #如果大于boxsize,就把x的值设为boxsize,y坐标值不变
    if f.xcor()<-boxsize:#检测当前的x坐标是否小于-boxsize
        f.goto(-boxsize,f.ycor())#如果小于,就把x的值设为-boxsize,y坐标值不变
    if f.ycor()>boxsize:#检测当前的y坐标是否大于设定的boxsize
        f.goto(f.xcor(),boxsize)#如果大于boxsize,就把y的值设为boxsize,x坐标值不变
    if f.ycor()<-boxsize:#检测当前的y坐标是否小于-boxsize
        f.goto(f.xcor(),-boxsize)#如果小于,就把y的值设为-boxsize,x坐标值不变

4.2.1代码解释
同时进行多重判断,当满足相应的条件时就执行相应的语句。此段程序中if语句主要用来检测boxsize是否满足相应的条件。

4.2.2使用方法
当一个程序中有多个条件需要同时判断时,就可用多个if条件语句进行判断,判断结果只有两个,要不为真,要不为假。格式如下:
If 条件语句:
执行语句
If 条件语句:
执行语句
If 条件语句:
执行语句

任务三:完成海龟抓鱼功能

1、任务分析
在任务二的基础上,我们增加一个小海龟的造型,让这个造型自动的进行“抓小鱼”的动作,从而实现小海龟抓鱼的功能。首先我们将设置一个布尔类型的变量,用来判断是否抓到小鱼,初始值设为否,也就是没有抓到小鱼。之后利用while循环语句判断,如果没有抓到小鱼则一直执行海龟跟着小鱼跑的动作,在此过程中不断地检测,直到海龟和小鱼的距离小于20时,则认为海龟抓到小鱼从而跳出循环。

2、编写程序
代码如下:
from turtle import Screen, Turtle#导入Screen库和turtle库
import time#导入时间函数
boxsize=300#设置一个坐标值为300的盒子
caught=False#设置布尔变量caught
f = Turtle()#赋值turtle给f
f.shape("classic")#库函数的默认形状为箭头
f.color("red")#设置小鱼的颜色为红色
f.penup()#提笔
#往前
def up():
  f.forward(10)
  checkbound()#调用检测鱼是否越界函数
#往后
def back():
  f.backward(10)
  checkbound()#调用检测鱼是否越界函数
#右转
def right():
  f.setheading(f.heading() + 10)#每次触发函数,转动方向加10
#左转
def left():
  f.setheading(f.heading() - 10)#每次触发函数,转动方向减10
  #检测老鼠是否跑过界
def checkbound():#自定义checkbound()
    global boxsize#定义全局变量boxsize
    if f.xcor()>boxsize:#检测当前的x坐标是否大于设定的boxsize
        f.goto(boxsize,f.ycor())#如果大于boxsize,就把x的值设为boxsize,y坐标值不变
    if f.xcor()<-boxsize:#检测当前的x坐标是否小于-boxsize
        f.goto(-boxsize,f.ycor())#如果小于,就把x的值设为-boxsize,y坐标值不变
    if f.ycor()>boxsize:#检测当前的y坐标是否大于设定的boxsize
        f.goto(f.xcor(),boxsize)#如果大于boxsize,就把y的值设为boxsize,x坐标值不变
    if f.ycor()<-boxsize:#检测当前的y坐标是否小于-boxsize
        f.goto(f.xcor(),-boxsize)#如果小于,就把y的值设为-boxsize,x坐标值不变
screen = Screen()
t=Turtle()
t.shape("turtle")
t.penup()
f.penup() #将鱼的画笔提起,使不会出现轨迹
f.goto(100,100)#设置鱼的初始位置
screen.listen()#调用screen的监听函数
#输入按键,触发对应的函数
screen.onkeypress(up,"Up")      #按动方向键Up则执行函数up
screen.onkeypress(left,"Left")
screen.onkeypress(right,"Right")
screen.onkeypress(back,"Down")
while not caught:
    t.setheading(t.towards(f))   #海龟调整自己方向,使自己正对鱼
    t.forward(8)
    if t.distance(f)<20:            #海龟与鱼的距离少于20个像素就输了
        caught=True       #抓到鱼时,设置布尔变量为true
        t.write("      捕获小鱼",font=('微软雅黑', 14, 'normal'))#显示中文提示
    time.sleep(0.2)    #设置海龟移动速度,数值越大移动越快
#点击屏幕退出
screen.exitonclick()

3、运行效果
运行程序,可以看屏幕内出现一个海龟在追小鱼,当我们通过键盘方向控制小鱼运动时,海龟尾随其后运动。当海龟和小鱼距离小鱼30时,说明海龟已经抓到小鱼,会弹窗“捕获小鱼”的中文提示

图片5.png 图片6.png


4、代码释义
4.1代码中的布尔变量的使用

caught=False#设置布尔变量caught
...........
caught=True
...........

4.1.1代码解释
设置一个布尔类型的变量caught,用来判断是否抓到小鱼,初始值设为false,也就是没有抓到小鱼,知道满足条件时,设置caught的值为true,从而跳出循环。

4.1.2布尔变量
Boolean Variable (布尔型变量) 是有两种逻辑状态的变量,它包含两个值:真(true)和假(false)。布尔型变量在运行时通常用做标志,比如进行逻辑测试以改变程序流程。示例程序中主要用来判断海龟和小鱼的距离是否小鱼,如果小鱼代表被抓到,从而跳出循环。

4.2代码中while循环和if语句的嵌套使用

while not caught:
    t.setheading(t.towards(f))   #海龟调整自己方向,使自己正对鱼
    t.forward(8)
    if t.distance(f)<20:            #海龟与鱼的距离少于20个像素就输了
        caught=True       #抓到鱼时,设置布尔变量为true
        t.write("      捕获小鱼",font=('微软雅黑', 14, 'normal'))#显示中文提示

4.2.1代码解释
当检测caught为假时,执行让海龟不断调整自己相对小鱼的方向,达到正面进行追逐的效果。此时用if判断海龟和鱼的距离是否小于20,当小于20时,设置caught的值为truet,在画布内显示“捕获小鱼”内容,之后跳出循环。

项目小结
本节课程我们首先学会通过键盘控制小鱼移动,之后设置范围让小鱼在规定范围内移动,最后完成了海龟抓鱼的功能。通过这个项目,我们对python的turtle库有了更深刻的体会,更是学会了键盘控制函数的使用、全局变量、多重if判断条件语句的使用、布尔变量、while循环和if语句的嵌套使用等知识。要让游戏更加有趣,想一想我们如何给这节课的功能中增加难度选择和计分功能呢?

项目扩展
增加难度选择和计分功能

参考程序
from turtle import Screen, Turtle#导入Screen库和turtle库
import time#导入时间函数
boxsize=300#设置一个坐标值为300的盒子
score=0#设置初始分数为0
caught=False#设置布尔变量caught
f = Turtle()#赋值turtle给f
f.shape("classic")#库函数的默认形状为箭头
f.color("red")#设置小鱼的颜色为红色
f.penup()#提笔
#往前
def up():
  f.forward(10)
  checkbound()#调用检测鱼是否越界函数
#往后
def back():
  f.backward(10)
  checkbound()#调用检测鱼是否越界函数
#右转
def right():
  f.setheading(f.heading() + 10)#每次触发函数,转动方向加10
#左转
def left():
  f.setheading(f.heading() - 10)#每次触发函数,转动方向减10
  #检测小鱼是否跑过界
def checkbound():#自定义checkbound()
    global boxsize#定义全局变量boxsize
    if f.xcor()>boxsize:#检测当前的x坐标是否大于设定的boxsize
        f.goto(boxsize,f.ycor())#如果大于boxsize,就把x的值设为boxsize,y坐标值不变
    if f.xcor()<-boxsize:#检测当前的x坐标是否小于-boxsize
        f.goto(-boxsize,f.ycor())#如果小于,就把x的值设为-boxsize,y坐标值不变
    if f.ycor()>boxsize:#检测当前的y坐标是否大于设定的boxsize
        f.goto(f.xcor(),boxsize)#如果大于boxsize,就把y的值设为boxsize,x坐标值不变
    if f.ycor()<-boxsize:#检测当前的y坐标是否小于-boxsize
        f.goto(f.xcor(),-boxsize)#如果小于,就把y的值设为-boxsize,x坐标值不变
screen = Screen()
t=Turtle()
t.shape("turtle")
t.penup()
f.penup() #将鱼的画笔提起,使不会出现轨迹
f.goto(100,100)#设置鱼的初始位置
screen.listen()#调用screen的监听函数
#输入按键,触发对应的函数
screen.onkeypress(up,"Up")      #按动方向键Up则执行函数up
screen.onkeypress(left,"Left")
screen.onkeypress(right,"Right")
screen.onkeypress(back,"Down")
#产生一个输入难度的对话框
difficulty=screen.numinput("难度","请输入游戏的难度(1~5)",minval=1,maxval=5)
#窗体监听按键
screen.listen()
while not caught:
    t.setheading(t.towards(f))   #海龟调整自己方向,使自己正对鱼
    t.forward(8+difficulty)
    score+=1
    if t.distance(f)<20:            #海龟和鱼的距离少于20个像素就输了
        caught=True
    time.sleep(0.2-(0.01*difficulty))    #难度越高,运行速度越快
screen.textinput("GAME OVER","游戏得分:"+str(score*difficulty))
screen.bye()   

附件:
7、小海龟抓鱼.rar (663.59 KB, 下载次数: 15)

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

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

硬件清单

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

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

mail