用python编写乒乓球小游戏–Turtle功能的应用
python有很多功能强大的代码库,Turtle是一款用于游戏开发的代码库。通过编写乒乓球小游戏可以了解这个库的基本的代码的使用
先创建游戏的背景,页面的话感觉跟matlab的交互页面的编辑还有easygui差不多。import os 与游戏本身无关,是为了后面可能添加音效而引用的
#创建游戏背景
import os
import turtle as t
game = t.Screen()
game.title("双人乒乓球对战")
game.bgcolor("black")
#os.system("pause") 或 input() 可以使程序暂停,不过此处使用可能导致程序直接终止,所以使用game.mianloop()
game.mainloop()
game.setup(800,600)
先创建一个球拍
这里必须提一下Turtle创建可视的对象的实质是创建一支画笔,有笔本身和笔所画出的轨迹。
#创建球拍
pai = t.Turtle() #对象其实是画笔
pai.ht() #隐藏球拍
pai.up() #隐藏轨迹
pai.speed(0) #运动速度为瞬移
pai.color("blue")
pai.shape('square')
pai.shapesize(5,1) #对上面的正方形进行拉伸
#根据800*400建立直角坐标系,进行移动
pai.goto(-350,0) #现在会有一条运动轨迹,所以第二条将其隐藏
pai.st() #到位后再显示出来
第二个球拍同理,只需要换个颜色和坐标。坐标(0,0)为显示框的正中央,再背景创建时。我规定坐标范围是(800,600),相当于800*600的矩形框,大家也可以自己调整,但是后面的代码都会发生变化
pai2 = t.Turtle()
pai2.ht()
pai2.up()
pai2.speed(0)
pai2.color("white")
pai2.shape('square')
pai2.shapesize(4,1)
pai2.goto(350,0)
pai2.st()
然后添加乒乓球(在这里我想到了植物大战僵尸的魔改版,其实也可以不抬起画笔(doge))
#添加乒乓球
ball = t.Turtle()
ball.up() #不需要隐藏但是不能画一条线
ball.speed(0)
ball.color("yellow")
ball.shape('circle') #d=20
ball.goto(0,0)
ball.st()
ball.vx = 2 #直接定义X轴和Y轴的速度
ball.vy = 2
player1score = 0
player2score = 0
现在考虑打印分数,最后一行的代码有许多函数的内置参数,感兴趣的朋友可以参考我另一则博客Turtle内置部分函数的用法
pen = t.Turtle() #创建一个画笔来打印分数
pen.ht() #隐藏最初的箭头,不影响书写(后面打印的字)
pen.up() #只要选定位置与初始化位置(0,0)不相符就会有轨迹
pen.color('white')
pen.goto(-10,260)
X = 'play1: {} play2: {}'.format(player1score,player2score)
pen.write(X,align='center',font=('Arial',20,'bold'))
最后让球拍和乒乓球动起来吧
这里的键位设定不知道是不是我电脑的原因(惠普的按键总是奇奇怪怪),只能开英文大写才行
#移动球拍
#自定义方向键
#先定义方法
def pai_up():
y = pai.ycor()
y = y + 12
pai.sety(y)
def pai_down():
y = pai.ycor()
y = y - 12
pai.sety(y)
def pai2_up():
y = pai2.ycor()
y = y + 12
pai2.sety(y)
def pai2_down():
y = pai2.ycor()
y = y - 12
pai2.sety(y)
game.listen() #听从玩家指令
game.onkey(pai_up,'W') #开始自定义键位,为了避免输入法的问题直接开大写
game.onkey(pai_down,'S')
game.onkey(pai2_up,'I')
game.onkey(pai2_down,'K')
#用循环使乒乓球动起来
while True:
ball.setx(ball.xcor()+ball.vx)
ball.sety(ball.ycor()+ball.vy)
if (ball.ycor() > 290) or (ball.ycor() < -290): #防止出界(只针对上下)--反弹--动量守恒
ball.vy *= -1
if (ball.xcor() > 390) or (ball.xcor() < -390):
ball.vx *= -1
if (ball.ycor() < pai2.ycor() + 50) and (ball.ycor() > pai2.ycor() - 50) and (ball.xcor() > 330):
ball.vx *= -1
if (ball.ycor() < pai.ycor() + 50) and (ball.ycor() > pai.ycor() -50) and (ball.xcor() < -330 ):
ball.vx *= -1
#判断出界
if ball.xcor() > 380 :
ball.goto(0,0)
player1score += 1
pen.clear()
X = 'play1: {} play2: {}'.format(player1score, player2score)
pen.write(X, align='center', font=('Arial', 20, 'bold'))
if ball.xcor() < -380:
player2score += 1
pen.clear() #作为幕布不会刷新,则需要认为地刷新(清除上一次的显示)
X = 'play1: {} play2: {}'.format(player1score, player2score)
pen.write(X, align='center', font=('Arial', 20, 'bold')) #这个方法被多次调用,为了简化也可以定义一个方法