- Python
Python turtle 弹球小游戏
- 2024-6-16 10:44:58 @
功能介绍
首先我们在屏幕上制作一个碰壁小球游戏,小球在指定区域内不断的碰壁反弹,之后新建一个拦球板对象,用来检测小球是否碰到拦球板,碰到则将积分增加,完成弹球小游戏的功能。课程会分为三个任务的形式进行,下表为课程任务及涉及到的知识点。
实现功能 | 知识点 |
---|---|
任务一:碰壁小球 | 巩固复习turtle库的两种不同导入方式、Screen函数以及学习随机数randint函数的使用 |
任务二:生成栏板对象 | 对象、属性、方法的概念及sleep()函数的使用 |
任务二:拦球小游戏 | 巩固学习获取鼠标坐标的方法、逻辑判断语句、多条件判断语句 |
项目实践
任务一:碰壁小球
1任务分析
前面我们已经学过了turtle库中Screen函数和Turtle函数的使用,这节课我们首先将巩固复习一下他们的用法,利用Screen函数创建一个屏幕,之后新建小球对象,让其在屏幕内不断的进行碰壁反弹运动。那么我们通过什么进行碰壁呢?下图为宽和高为w和h的屏幕。
通过上图屏幕我们可以看出判断左右是否碰到壁,其实可以通过检测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运行效果
运行这段程序,我们可以看到弹出了一个星空背景的屏幕,屏幕内有一个黄色小球在不断的进行碰壁反弹运动。
任务二:生成拦球杆对象
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运行效果
运行程序我们发现,呈现的屏幕内小黄球还是在不断的碰壁反弹运动,此可以看到比任务一多了一个蓝色的小栏板。
任务三:拦球小游戏
1任务分析
通过任务二我们建立了拦球板,现在我们需要通过鼠标去控制拦球板的运动,之后设置一个计分的变量,让小球碰到篮球板就反弹回去的同时计分加一,如果小球没有碰到篮球板但是碰到了下边界,那么就结束游戏,停止游戏。分为以下两步进行。
第一步:实现鼠标控制小拦板移动
这里我们只需要控制小栏板左右移动,所以我们只需获取小拦板在画布内x坐标就好了。
第二步:判断游戏是否继续
其次我们要解决判断游戏是否继续,这里我们可以通过判断小球的横坐标和纵坐标是否在栏板的范围内。下图分别为成功和失败的例图
成功
碰到小栏板需反弹
失败
没碰到小栏板,碰到了下边界
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运行效果
点击运行程序,我们可以看到小球开始向右上方移动,碰到屏幕的上方,左右两侧及栏板后就反弹。这时,我们可以通过鼠标来控制我们的栏板移动进而接球,栏板与小球每接触一次,我们就记一次得分并显示在终端中。如果小拦板接不到小球,并且小球碰到了下边界,那么游戏就会停止。基于这样的游戏功能让我们一起来试试吧,看看最高能得多少分呢?
项目小结
通过本节课程的学习我们巩固复习turtle库的两种不同导入方式、Screen函数以及学习随机数randint函数的使用完成了碰壁小球游戏。之后建立小栏板对象,理解了对象、属性、方法的概念。最终完成拦球小游戏功能,巩固学习了获取鼠标坐标的方法、逻辑运算符、多条件判断语句等的用法。想一想作为一个游戏是不是还有很多可以加入控制的功能,比如如何增加游戏难度选择和游戏胜利提醒?
项目扩展
尝试换一个背景,然后增加游戏难度设置和游戏胜利提示功能。
参考代码
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,否则很卡
#---------------------------------------------------
#产生一个输入难度的对话框
difficulty=screen.numinput("难度","请输入游戏的难度(1~5)",minval=1,maxval=5)
square = turtle.Turtle('square')#创建一个弹球小栏板
square.shapesize(0.5,10/difficulty)#设定栏板的长宽尺寸
square.speed(0)#设定栏板速度为最大
square.penup()#抬笔
square.color('blue')#设定颜色为蓝色
#----------------------------------------------------
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()#画布到计算机屏幕最左边距离
x = mx - rx - 2#画布边框宽度是2,所以要减去2
x = x - screen.window_width() //2 # 转换成在海龟画图坐标系中x坐标
square.goto(x,-100/difficulty)#使栏板移动到指定坐标
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:#如果小球过了下边界
turtle.write("game over",font=("Arial",40,"normal"))#显示失败
else:
ball.goto(x,y)#设定小球的移动
squareleftx = square.xcor() - 10/difficulty*10#设定栏板的左侧横坐标
squarerightx = square.xcor() + 10/difficulty*10#设定栏板的右侧横坐标
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()#刷新屏幕显示
if count == 5*difficulty:#如果得了50分
print("victory")#显示获胜
turtle.exitonclick()#点击退出
sleep(0.01)#推迟0.01秒再执行
1 条评论
-
mrhowe SU @ 2024-6-16 11:57:44
from turtle import *#导入turtle库的所有工具 from random import randint #导入random的randint工具 from time import sleep#导入time的sleep工具 w,h= 800,600#设置屏幕的宽和高 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对象,形状为圆形 square ball.speed(0)#设置ball的速度为最快. ball.penup()#提笔,不留痕迹 ball.color("red","blue")#设置ball的边框颜色填充颜色 x速度 = randint(2,8)#设置初始水平速度 y速度 = randint(2,8)#设置初始垂直速度 #------------------------- root = screen._root#获取根窗口对象 cv = screen._canvas#获取画布 count = 0#计次数 while True :#永久循环 mx = root.winfo_pointerx()#鼠标指针相对于计算机屏幕的x坐标 rx = cv.winfo_rootx()#画布到计算机屏幕最左边距离 x = mx - rx - 2#画布边框宽度是2,所以要减去2 x = x - screen.window_width() //2 # 转换成在海龟画图坐标系中x坐标 square.goto(x,50-h/2)#使栏板移动到指定坐标 screen.update()#刷新屏幕显示 #----------------------------------------------------- x=ball.xcor() + x速度#获取移动前ball的x坐标值加上小球速度的速度值,得到移动后x坐标值 y=ball.ycor() + y速度#获取移动前ball的y坐标值加上小球速度的速度值,得到移动后y坐标值 ball.goto(x,y)#让小球到达坐标为(x,y)的坐标点 dx = square.xcor() dy = square.ycor() # print(dx,dy) print(x,y) if y< dy+5+20 and x>dx-50+20 and x<dx+50-20: y速度 = -y速度#如果碰到挡板就同一速度反方向弹开 if x>w/2-20 or x<-w/2+20:#判断ball是否碰左右边缘的壁 x速度 = -x速度#如果碰到壁就同一速度反方向弹开 if y>h/2-20 or y<-h/2+20:#判断ball是否碰上下边缘的壁 y速度 = -y速度#如果碰到壁就同一速度反方向弹开 sleep(0.01)#推迟0.01秒再执行
- 1