2021-10-14 15:45:20 [显示全部楼层]
10437浏览
查看: 10437|回复: 0

[教程] Mind+Python turtle 课程——08 弹球小游戏

[复制链接]
Mind+Python turtle 课程-08 弹球小游戏

课程目录:


功能介绍

经过前面课程的学习,我们已经掌握了利用turtle库创建屏幕的方式,也了解了在屏幕上如何获取鼠标指针的坐标。这节课将作为巩固课,主要巩固我们前面所学的知识,首先我们在屏幕上制作一个碰壁小球游戏,小球在指定区域内不断的碰壁反弹,之后新建一个拦球板对象,用来检测小球是否碰到拦球板,碰到则将积分增加,完成弹球小游戏的功能。课程会分为个任务的形式进行,下表为课程任务及涉及到的知识点。

实现功能
知识点
任务一:碰壁小球
巩固复习turtle库的两种不同导入方式、Screen函数以及学习随机数randint函数的使用
任务二:生成栏板对象
对象、属性、方法的概念及sleep()函数的使用
任务二:拦球小游戏
巩固学习获取鼠标坐标的方法、逻辑判断语句、多条件判断语句

背景图片下载:
链接:https://pan.baidu.com/s/1NkWgpmbwwixKAr5miJuwfA
提取码:lxdb

项目实践

任务一:碰壁小球

1任务分析
前面我们已经学过了turtle库中Screen函数和Turtle函数的使用,这节课我们首先将巩固复习一下他们的用法,利用Screen函数创建一个屏幕,之后新建小球对象,让其在屏幕内不断的进行碰壁反弹运动。那么我们通过什么进行碰壁呢?下图为宽和高为w和h的屏幕。

Mind+Python turtle 课程——08 弹球小游戏图1

通过上图屏幕我们可以看出判断左右是否碰到壁,其实可以通过检测x轴的坐标是否大于w/2或者小于-w/2来判断,也就是当x轴的坐标大于w/2或者小于-w/2时证明小球碰到了左右壁。而判断上下是否碰到壁,可以通过检测y轴的坐标是否大于h/2或者小于-h/2来判断,也就是当y轴的坐标大于h/2或者小于-h/2时证明小球碰到了上下壁。

2编写程序

from turtle import *#导入turtle库的所有工具
from random import randint #导入random的randint工具
from time import sleep#导入time的sleep工具
w,h= 480,360#设置屏幕的宽和高
screen = Screen()#把Screen的对象赋值给screen
screen.bgcolor("black")#设置屏蔽背景为黑色
screen.setup(w,h)#初始设置宽和高
screen.bgpic("Background.gif") #背景设置#
#-------------------------
ball=Turtle(shape='circle')#新建ball对象,形状为圆形
ball.speed(0)#设置ball的速度为最快.
ball.penup()#提笔,不留痕迹
ball.color("yellow","yellow")#设置ball的边框颜色填充颜色
x速度 = randint(2,3)#设置初始水平速度
y速度 = randint(2,3)#设置初始垂直速度
while True :#永久循环
    x=ball.xcor() + x速度#获取移动前ball的x坐标值加上小球速度的速度值,得到移动后x坐标值
    y=ball.ycor() + y速度#获取移动前ball的y坐标值加上小球速度的速度值,得到移动后y坐标值
    ball.goto(x,y)#让小球到达坐标为(x,y)的坐标点
    if x>w/2 or x<-w/2:#判断ball是否碰左右边缘的壁
        x速度 = -x速度#如果碰到壁就同一速度反方向弹开
    if y>h/2 or y<-h/2:#判断ball是否碰上下边缘的壁
        y速度 = -y速度#如果碰到壁就同一速度反方向弹开

3运行效果

运行这段程序,我们可以看到弹出了一个星空背景的屏幕,屏幕内有一个黄色小球在不断的进行碰壁反弹运动。

Mind+Python turtle 课程——08 弹球小游戏图2

4代码释义

4.1代码中randint函数的使用

x速度 = randint(2,3)#设置初始水平速度
y速度 = randint(2,3)#设置初始垂直速度

4.1.1代码解释
通过rendint函数在指定范围内生成一个小球的运动速度,代码中分别设置了小球的水平速度和垂直速度,并且规定最大值为3,最小值为2。

4.1.2randint函数
turtle中randint(a,b)用于生成一个指定范围内的整数。其中参数a是下限,参数b是上限,生成的随机数n: a <= n <= b。

任务二:生成拦球杆对象

1任务分析
在任务一中,我们已经绘制了一个星空背景的屏幕,并让黄色小球在不断的进行碰壁反弹运动。这里我们需要生成另一个对象,也就是拦球杆,用来拦下小球。

2编写程序
from turtle import *#导入turtle库的所有工具
from random import randint #导入random的randint工具
from time import sleep#导入time的sleep工具
w,h= 480,360#设置屏幕的宽和高
screen = Screen()#把Screen的对象赋值给screen
screen.bgcolor("black")#设置屏蔽背景为黑色
screen.setup(w,h)#初始设置宽和高
screen.bgpic("Background.gif") #背景设置#
screen.delay(0)#这里要设为0,否则很卡
#---------------------------------------------------
square =Turtle('square')#创建一个弹球小栏板
square.shapesize(0.5,5)#设定栏板的长宽尺寸,对应像素为高5像素,长为50像素
square.speed(0)#设定栏板速度为最大
square.penup()#抬笔
square.color('blue')#设定颜色为蓝色
square.sety(50-h/2)#固定纵坐标
#----------------------------------------------------
ball=Turtle(shape='circle')#新建ball对象,形状为圆形
ball.speed(0)#设置ball的速度为最快.
ball.penup()#提笔,不留痕迹
ball.color("yellow","yellow")#设置ball的填充和边框颜色
x速度 = randint(2,3)#设置初始水平速度
y速度 = randint(2,3)#设置初始垂直速度
while True :#永久循环
    x=ball.xcor() + x速度#获取移动前ball的x坐标值加上小车速度,得到移动后x坐标值
    y=ball.ycor() + y速度#获取移动前ball的y坐标值加上小车速度,得到移动后y坐标值
    ball.goto(x,y)#让小球到达坐标为(x,y)的坐标点
    if x>w/2 or x<-w/2:#判断ball是否碰左右边缘的壁
        x速度 = -x速度#如果碰到壁就同一速度反方向弹开
    if y>h/2 or y<-h/2:#判断ball是否碰上下边缘的壁
        y速度 = -y速度#如果碰到壁就同一速度反方向弹开
    sleep(0.01)#推迟0.01秒再执行

注意:这里一定要加上sleep(0.01)否则小球会弹得很快,无法看清效果

3运行效果
运行程序我们发现,呈现的屏幕内小黄球还是在不断的碰壁反弹运动,此可以看到比任务一多了一个蓝色的小栏板。

Mind+Python turtle 课程——08 弹球小游戏图3

4代码释义

4.1代码中对象的使用

square =Turtle('square')#创建一个弹球小栏板对象
square.shapesize(0.5,5)#设定栏板的长宽尺寸
square.speed(0)#设定栏板速度为最大
square.penup()#抬笔
square.color('blue')#设定颜色为蓝色
square.sety(50-h/2)#固定纵坐标  
#----------------------------------------------------
ball=Turtle(shape='circle')#新建ball对象,形状为圆形
ball.speed(0)#设置ball的速度为最快.
ball.penup()#提笔,不留痕迹
ball.color("yellow","yellow")#设置ball的填充和边框颜色

4.1.1代码解释
生成两个对象分别是小球和篮球板,并设置它们的相关属性和方法。

4.1.2什么是对象
Python中定义什么是对象,拿球做例子。可以操作一个球,比如捡球、踢球、抛球等。我们把这些操作称为动作。还可以通过颜色、重量和大小来描述一个球。这些就是球的属性。在Python中,一个对象的特征也称为属性,动作称为方法。

4.1.3什么是属性
属性就是你所知道的关于球的所有方面,包括球的形状、大小、颜色、重量等

4.1.3什么是方法
方法就是可以对对象做的操作,它们是一些代码块。可以调用这些代码来完成某个工作,是不是很熟悉?方法其实就是在对象中的函数。函数能做到的,方法都能做到,包括传递参数和返回值。所以利用对象,可以把一个东西的属性和方法收集到一起

任务三:拦球小游戏

1任务分析
通过任务二我们建立了拦球板,现在我们需要通过鼠标去控制拦球板的运动,之后设置一个计分的变量,让小球碰到篮球板就反弹回去的同时计分加一,如果小球没有碰到篮球板但是碰到了下边界,那么就结束游戏,停止游戏。分为以下两步进行。

第一步:实现鼠标控制小拦板移动
其实原理和第六课小海龟走迷宫一样,这里我们只需要控制小栏板左右移动,所以我们只需获取小拦板在画布内x坐标就好了。

Mind+Python turtle 课程——08 弹球小游戏图4

第二步:判断游戏是否继续
其次我们要解决判断游戏是否继续,这里我们可以通过判断小球的横坐标和纵坐标是否在栏板的范围内。下图分别为成功和失败的例图
成功
碰到小栏板需反弹
Mind+Python turtle 课程——08 弹球小游戏图5
失败
没碰到小栏板,碰到了下边界
Mind+Python turtle 课程——08 弹球小游戏图6

2编写程序
import turtle#导入turtle库
from random import randint#导入随机数库randint函数
from time import sleep#导入时间库sleep函数
#-------------------------------------------------------
screen = turtle.Screen()#赋值screen对象
w,h= 480,360#设定宽度和高度
screen.setup(w,h)#以设定好的宽度和高度来创建屏幕
screen.bgcolor("green")#设定背景色为绿色
screen.delay(0)#这里要设为0,否则很卡
#---------------------------------------------------
square = turtle.Turtle('square')#创建一个弹球小栏板
square.shapesize(0.5,5)#设定栏板的长宽尺寸,对应像素为高5像素,长为50像素
square.speed(0)#设定栏板速度为最大
square.penup()#抬笔
square.color('blue')#设定颜色为蓝色
square.sety(50-h/2)#固定纵坐标  
#----------------------------------------------------
ball=turtle.Turtle(shape='circle')#创建一个圆球
ball.speed(0)#速度为最快.
ball.penup()#抬笔
ball.color("yellow","yellow")#设定颜色为黄色
xspeed = randint(2,3)#设置初始水平速度
yspeed = randint(2,3)#设置初始垂直速度
#-----------------------------------------------------
root = screen._root#获取根窗口对象
cv = screen._canvas#获取画布
count = 0#计次数
while True:#永久循环
    mx = root.winfo_pointerx()#鼠标指针相对于计算机屏幕的x坐标
    rx = cv.winfo_rootx()#画布到计算机屏幕最左边距离
    bx = mx - rx - 2#画布边框宽度是2,所以要减去2  
    x = bx - screen.window_width() //2  # 转换成在海龟画图坐标系中x坐标
    square.goto(x,-50)#使栏板移动到指定坐标
    screen.update()#刷新屏幕显示
#-----
    x = ball.xcor() + xspeed#设置小球在水平方向移动x速度
    y= ball.ycor() + yspeed#设置小球在垂直方向移动y速度
    ball.goto(x,y)#设定小球的移动
    if  x>w/2 or x <-w/2:#如果小球跑出左右两侧边界
        xspeed  = - xspeed#设定小球返回   
    elif  y>h/2 :#如果小球过了上边界
        yspeed = - yspeed#设定小球返回
elif  y<-h/2:#如果小球过了下边界
        print("game over")#显示得分
        turtle.done()#画面停止
    else:
         ball.goto(x,y)#设定小球的移动
    squareleftx = square.xcor() - 50#设定栏板的左侧横坐标
    squarerightx = square.xcor() + 50#设定栏板的右侧横坐标
    squareupy = square.ycor() + 5#设定栏板的上方纵坐标
    squaredowny = square.ycor() - 5#设定栏板的下端纵坐标
    if x< squarerightx and x >squareleftx:#如果小球的横坐标在栏板的范围内
        if y < squareupy and y > squaredowny:#如果小球的纵坐标在栏板范围内
            yspeed = - yspeed#反弹
            count=count+1#计次
            print("得分:",count)#显示得分
            screen.update()#刷新屏幕显示
    sleep(0.01)#推迟0.01秒再执行

3运行效果
点击运行程序,我们可以看到小球开始向右上方移动,碰到屏幕的上方,左右两侧及栏板后就反弹。这时,我们可以通过鼠标来控制我们的栏板移动进而接球,栏板与小球每接触一次,我们就记一次得分并显示在终端中。如果小拦板接不到小球,并且小球碰到了下边界,那么游戏就会停止。基于这样的游戏功能让我们一起来试试吧,看看最高能得多少分呢?

Mind+Python turtle 课程——08 弹球小游戏图7

4代码释义

4.1获取鼠标坐标控制小拦板移动
  1. while True:#永久循环
  2.       mx = root.winfo_pointerx()#鼠标指针相对于计算机屏幕的x坐标
  3.       rx = cv.winfo_rootx()#画布到计算机屏幕最左边距离
  4.       bx = mx - rx - 2#画布边框宽度是2,所以要减去2  
  5.       x = bx - screen.window_width() //2  # 转换成在海龟画图坐标系中x坐标
  6.       square.goto(x,-50)#使栏板移动到指定坐标
  7.       screen.update()#刷新屏幕显示
复制代码

4.1.1代码解释
通过获取电脑中的鼠标的x轴的坐标mx画布到计算机屏幕最左边距离rx,计算出鼠标距离画布边缘的距离bx,之后用得到的bx减去画布宽度值的一半来获取鼠标相对于画布的坐标值x。

Mind+Python turtle 课程——08 弹球小游戏图8

4.1.1使用方法
相对于x坐标,以后如果需要通过鼠标去控制相应的运动,即可套用这个公式从而获得当前鼠标相对于当前画布的坐标值,从而实现坐标控制其运动。
  1. mx = root.winfo_pointerx()#鼠标指针相对于计算机屏幕的x坐标
  2.     rx = cv.winfo_rootx()#画布到计算机屏幕最左边距离
  3.     bx = mx - rx - 2#画布边框宽度是2,所以要减去2  
  4.     x = bx - screen.window_width() //2  # 转换成在海龟画图坐标系中x坐标
复制代码

4.2判断是否继续
  1. squareleftx = square.xcor() - 50#设定栏板的左侧横坐标
  2.     squarerightx = square.xcor() + 50#设定栏板的右侧横坐标
  3.     squareupy = square.ycor() + 5#设定栏板的上方纵坐标
  4.     squaredowny = square.ycor() - 5#设定栏板的下端纵坐标
  5.     if x< squarerightx and x >squareleftx:#如果小球的横坐标在栏板的范围内
  6.       if y < squareupy and y > squaredowny:#如果小球的纵坐标在栏板范围内
  7.             yspeed = - yspeed#反弹
  8.             count=count+1#计次
  9.             print("得分:",count)#显示得分
  10.             screen.update()#刷新屏幕显示
复制代码

4.1.1代码解释
因为我们前面设定了小拦板的尺寸为square.shapesize(0.5,5),也就是像素高为5,长为50的小栏板。

Mind+Python turtle 课程——08 弹球小游戏图9

而我们通过代码可以获取小拦板中心点的坐标square.xcor(),square.ycor())。因此在计算其最边缘的坐标时需要减去或加上square本身的像素值。既左边减50,右边加50,上边加5,下边减5。从而获得当前小拦板的对应边缘的坐标值。之后进行判断,如果小球的坐标没有超出小拦板的坐标时,表示小球碰到了栏板,继而获得一分将得分加一,同时通过终端实时的打印当前的得分情况。否则游戏停止,终端打印game over。

项目小结
通过本节课程的学习我们巩固复习turtle库的两种不同导入方式、Screen函数以及学习随机数randint函数的使用完成了碰壁小球游戏。之后建立小栏板对象,理解了对象、属性、方法的概念。最终完成拦球小游戏功能,巩固学习了获取鼠标坐标的方法、逻辑运算符、多条件判断语句等的用法。想一想作为一个游戏是不是还有很多可以加入控制的功能,比如如何增加游戏难度选择和游戏胜利提醒?

项目扩展
尝试换一个背景,然后增加游戏难度设置和游戏胜利提示功能。

参考程序
  1. import turtle#导入turtle库
  2. from random import randint#导入随机数库randint函数
  3. from time import sleep#导入时间库sleep函数
  4. #-------------------------------------------------------
  5. screen = turtle.Screen()#赋值screen对象
  6. w,h= 480,360#设定宽度和高度
  7. screen.setup(w,h)#以设定好的宽度和高度来创建屏幕
  8. screen.bgcolor("green")#设定背景色为绿色
  9. screen.delay(0)#这里要设为0,否则很卡
  10. #---------------------------------------------------
  11. #产生一个输入难度的对话框
  12. difficulty=screen.numinput("难度","请输入游戏的难度(1~5)",minval=1,maxval=5)
  13. square = turtle.Turtle('square')#创建一个弹球小栏板
  14. square.shapesize(0.5,10/difficulty)#设定栏板的长宽尺寸
  15. square.speed(0)#设定栏板速度为最大
  16. square.penup()#抬笔
  17. square.color('blue')#设定颜色为蓝色
  18. #----------------------------------------------------
  19. ball=turtle.Turtle(shape='circle')#创建一个圆球
  20. ball.speed(0)#速度为最快.
  21. ball.penup()#抬笔
  22. ball.color("yellow","yellow")#设定颜色为黄色
  23. xspeed = randint(2,3)#设置初始水平速度
  24. yspeed = randint(2,3)#设置初始垂直速度
  25. #-----------------------------------------------------
  26. root = screen._root#获取根窗口对象
  27. cv = screen._canvas#获取画布
  28. count = 0#计次数
  29. while True:#永久循环
  30.     mx = root.winfo_pointerx()#鼠标指针相对于计算机屏幕的x坐标
  31.     rx = cv.winfo_rootx()#画布到计算机屏幕最左边距离
  32.     x = mx - rx - 2#画布边框宽度是2,所以要减去2  
  33.     x = x - screen.window_width() //2  # 转换成在海龟画图坐标系中x坐标
  34.     square.goto(x,-100/difficulty)#使栏板移动到指定坐标
  35.     screen.update()#刷新屏幕显示
  36. #-----------------------------------------------------
  37.     x = ball.xcor() + xspeed#设置小球在水平方向移动x速度
  38.     y= ball.ycor() + yspeed#设置小球在垂直方向移动y速度
  39.     ball.goto(x,y)#设定小球的移动
  40.     if  x>w/2 or x <-w/2:#如果小球跑出左右两侧边界
  41.         xspeed  = - xspeed#设定小球返回   
  42.     elif  y>h/2 :#如果小球过了上边界
  43.         yspeed = - yspeed#设定小球返回
  44.     elif  y<-h/2:#如果小球过了下边界
  45.         turtle.write("game over",font=("Arial",40,"normal"))#显示失败
  46.     else:
  47.          ball.goto(x,y)#设定小球的移动
  48.     squareleftx = square.xcor() - 10/difficulty*10#设定栏板的左侧横坐标
  49.     squarerightx = square.xcor() + 10/difficulty*10#设定栏板的右侧横坐标
  50.     squareupy = square.ycor() + 5#设定栏板的上方纵坐标
  51.     squaredowny = square.ycor() - 5#设定栏板的下端纵坐标
  52.     if x< squarerightx and x >squareleftx:#如果小球的横坐标在栏板的范围内
  53.         if y < squareupy and y > squaredowny:#如果小球的纵坐标在栏板范围内
  54.             yspeed = - yspeed#反弹
  55.             count=count+1#计次
  56.             print("得分:",count)#显示得分
  57.             screen.update()#刷新屏幕显示
  58.     if count == 5*difficulty:#如果得了50分
  59.         print("victory")#显示获胜
  60.         turtle.exitonclick()#点击退出
  61.     sleep(0.01)#推迟0.01秒再执行
复制代码



参考效果
Mind+Python turtle 课程——08 弹球小游戏图10


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

本版积分规则

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

硬件清单

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

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

mail