原标题:Python游戏设计入门
精品小课,服务大众
turtle库是Python自带的基本绘图库,是初学Python同学最好的一个入门的工具。为了完成弹球游戏,我们第一步导入turtle库。
新建一个屏幕对象实例,设定窗口的标题内容为“ 大学计算机基础”,设置窗口的大小水平为 800 像素,垂直为 600像素,背景填充颜色为经典的黑色(字符串类型)。
# 导入绘图库
import turtle
wn = turtle.Screen
wn.title("大学计算机基础")
wn.setup( 800 , 600 )
wn.bgcolor("black")
wn.tracer( 0 )
测试结果窗口
从turtle模块中新建一个Turtle类,取名为paddleA对象实例,设置速度最快(无动画效果),形状为正方形,颜色为白色,位置在平面的左侧,画笔抬起(移动过程中不会绘制线段),正方形进行拉伸,变成一个矩形条。
进入游戏主循环,不断更新窗口内容(进行重绘)。
注意:turtle默认的 形状尺寸为 20X20 像素。
# 档板A
paddleA = turtle.Turtle
paddleA.speed( 0 )
paddleA.shape("square")
paddleA.color("white")
paddleA.goto( -350, 0 )
paddleA.penup
paddleA.shapesize( stretch_wid = 5, stretch_len = 1)
# 游戏主循环
while True:
wn.update #更新窗口
新增档板B和 小球ball
小球有2个属性即移动中X坐标与Y坐标的增量。
# 档板A
paddleA = turtle.Turtle
paddleA.speed( 0 )
paddleA.shape("square")
paddleA.color("white")
paddleA.goto( -350, 0 )
paddleA.penup
paddleA.shapesize( stretch_wid = 5, stretch_len = 1)
# 档板B
paddleB = turtle.Turtle
paddleB.speed( 0 )
paddleB.shape("square")
paddleB.color("white")
paddleB.goto( 350, 0 )
paddleB.penup
paddleB.shapesize( stretch_wid = 5, stretch_len = 1)
# 小球 ball
ball=turtle.Turtle #turtle 模块名,Turtle 类名 实例初始化
ball.speed(0) #0最快速度,1-9级不同速度
ball.shape("circle") #shape 形状:square circle,trianle...
ball.color("white") #物品原色,默认颜色是黑色
ball.penup #状态 抬笔
ball.dx= 0.1 #水平方向移动距离
ball.dy= -0.1 #垂直方向移动距离
#游戏主循环
while True:
wn.update #更新窗口
最终有3个对象的窗口
下面随小编一起新增4个函数,控制A、B档板上下移动(20个像素单位),并且对wn对象添加一个 事件侦听方法,通过wn的方法onkeypress 绑定具体按键与函数的对应关系(建议大家看懂它的逻辑)。
#定义一个函数,移动挡板向上
def paddleA_up:
y=paddleA.ycor#返回当前的Y坐标
y=y+20
paddleA.sety(y)#设置当前的Y坐标
#定义一个函数,移动挡板向下
def paddleA_down:
y=paddleA.ycor#返回当前的Y坐标
y=y-20
paddleA.sety(y)#设置当前的Y坐标
#定义一个函数,移动挡板向上
def paddleB_up:
y=paddleB.ycor#返回当前的Y坐标
y=y+20
paddleB.sety(y)#设置当前的Y坐标
#定义一个函数,移动挡板向下
def paddleB_down:
y=paddleB.ycor#返回当前的Y坐标
y=y-20
paddleB.sety(y)#设置当前的Y坐标
#玩家需要按w向上,s向下
wn.listen#事件侦听
wn.onkeypress(paddleA_up,"w") #按下去的键的侦测
wn.onkeypress(paddleA_down,"s") #按下去的键的侦测
wn.onkeypress(paddleB_up,"Up") #按下去的键的侦测
wn.onkeypress(paddleB_down,"Down") #按下去的键的侦测
可以通过键盘上的 w,s , ↑,↓按键,
分别控制档板A和档板B的向上向下移动
在主游戏循环模块中,新增小球移动代码,它的移动有4种不同情况(因为反弹的关系),分别如下图所示:
#主游戏主循环
while True:
wn.update #窗口刷新
#让小球不断移动
ball.setx( ball.xcor + ball.dx )
ball.sety( ball.ycor + ball.dy )
#上边界检测
if ball.ycor>290:
ball.sety(290)
ball.dy=ball.dy*(-1)
#下边界检测,反向
if ball.ycor<-290:
ball.sety(-290)
ball.dy=ball.dy*(-1)
#右边界检测
if ball.xcor>390:
ball.setx(390)
ball.dx=ball.dx*(-1)
#左边界检测,反向
if ball.xcor<-390:
ball.setx(-390)
ball.dx=ball.dx*(-1)
浅红色为新增代码块
碰到下边界(进入右下,出来右上)
碰到下边界(进入左下,出来左上)
碰到上边界(进入左上,出来左下)
碰到上边界(进入右上,出来右下)
碰到右边界(进入右上,出来左上)
碰到右边界(进入右下,出来左下)
碰到左边界(进入左下,出来右下)
碰到左边界(进入左上,出来右上)
本项目中最难部分,就是小球碰到档板B 的反弹的条件逻辑设定如下
(1)小球的X坐标大于 340 并且,小于350 (从水平方向来看)
(2) 小球的X坐标大于 档板Y坐标 - 40 并且小于 档板Y坐标 + 40
小球碰到档板B 的反弹的条件逻辑设定如下
(1)小球的X坐标小于 -340 并且,大于 -350 (从水平方向来看)
(2)小球的X坐标大于 档板Y坐标 - 40 并且 小于档板Y坐标 + 40
#主游戏主循环
while True:
#小球碰到挡板B反弹
if (ball.xcor< 350 and ball.xcor>340) and (ball.ycor< paddleB.ycor+40 and ball.ycor>paddleB.ycor-40):
ball.setx(340)
ball.dx=ball.dx*(-1)
#小球碰到挡板A反弹
if (ball.xcor>-350 and ball.xcor<-340) and (ball.ycor< paddleA.ycor+40 and ball.ycor>paddleA.ycor-40):
ball.setx(-340)
ball.dx=ball.dx*(-1)
浅红色为新增代码块
小球碰到档板B反弹
小球碰到档板A反弹
添加2个变量Score_A 和 Score_B ,记录玩家A和玩家B的游戏得分。pen对象实例是在窗口的正上方绘制文本(本身隐藏的),计分规则很简单,小球碰到左边边缘,玩家B加一分(A不扣分), 小球碰到右边边缘,玩家A加一分(B不扣分),具体的代码如下,如果逻辑上不明白可以给小编留言。
#计分变量
Score_A=0#玩家A的得分
Score_B=0#玩家A的得分
#游戏的计分系统
pen=turtle.Turtle
pen.speed(0)
pen.color("white")
pen.penup
pen.hideturtle#隐藏画笔
pen.goto(0,260)#中间正上方
showText= f"玩家A得分{Score_A},玩家B得分{Score_B}"
pen.write(showText,align="center",font=("Courier",24,"bold"))
while True:
#右边界检测
if ball.xcor>390:
ball.setx(390)
ball.dx=ball.dx*(-1)
Score_A+=1
pen.clear
showText= f"玩家A得分{Score_A},玩家B得分{Score_B}"
pen.write(showText,align="center",font=("Courier",24,"bold"))
#左边界检测,反向
if ball.xcor<-390:
ball.setx(-390)
ball.dx=ball.dx*(-1)
Score_B+=1
pen.clear
showText= f"玩家A得分{Score_A},玩家B得分{Score_B}"
pen.write(showText,align="center",font=("Courier",24,"bold"))
最后给游戏添加一些音效,让游戏有更好的体验感。
注意:Bounce.wav 和 Win.wav文件需要与Python源文件在同一目录下。
import turtle #导入乌龟库。Pygame
import winsound #播放声音的库
#主游戏主循环
while True:
wn.update #窗口刷新
#上边界检测
if ball.ycor>290:
ball.sety(290)
ball.dy=ball.dy*(-1)
winsound.PlaySound("Bounce.wav",winsound.SND_ASYNC)#播放声音
#下边界检测,反向
if ball.ycor<-290:
ball.sety(-290)
ball.dy=ball.dy*(-1)
winsound.PlaySound("Bounce.wav",winsound.SND_ASYNC)#播放声音
#右边界检测
if ball.xcor>390:
ball.setx(390)
ball.dx=ball.dx*(-1)
Score_A+=1
pen.clear
showText= f"玩家A得分{Score_A},玩家B得分{Score_B}"
pen.write(showText,align="center",font=("Courier",24,"bold"))
winsound.PlaySound("Win.wav",winsound.SND_ASYNC)#同步播放声音
#左边界检测,反向
if ball.xcor<-390:
ball.setx(-390)
ball.dx=ball.dx*(-1)
Score_B+=1
pen.clear
showText= f"玩家A得分{Score_A},玩家B得分{Score_B}"
pen.write(showText,align="center",font=("Courier",24,"bold"))
winsound.PlaySound("Win.wav",winsound.SND_ASYNC)#播放声音
#碰到挡板B反弹
if (ball.xcor< 350 and ball.xcor>340) and (ball.ycor< paddleB.ycor+40 and ball.ycor>paddleB.ycor-40):
ball.setx(340)
ball.dx=ball.dx*(-1)
winsound.PlaySound("Bounce.wav",winsound.SND_ASYNC)#播放声音
#碰到挡板A反弹
if (ball.xcor>-350 and ball.xcor<-340) and (ball.ycor< paddleA.ycor+40 and ball.ycor>paddleA.ycor-40):
ball.setx(-340)
ball.dx=ball.dx*(-1)
winsound.PlaySound("Bounce.wav",winsound.SND_ASYNC)#播放声音
责任编辑: