前提
要确保代码能运行,请确认你安装了相关的python库
在python命令行中运行如下命令:
pip install tkinter
参考书籍:tkinter菜鸟编程
具体讲解
导入相关库
from tkinter import *
from random import *
import time
定义球类
class Ball:
def __init__(self, canvas, color, winW, winH, racket):
self.canvas = canvas
self.racket = racket
self.id = canvas.create_oval(0, 0, 20, 20, fill=color)
self.canvas.move(self.id, winW/2, winH/2)
startPos = [-4, -3, -2, -1, 1, 2, 3, 4]
shuffle(startPos)
self.x = startPos[0]
self.y = -step
self.notTouchBottom= True
def hitRacket(self, ballPos):
racketPos = self.canvas.coords(self.racket.id)
if ballPos[2] >= racketPos[0] and ballPos[0] <= racketPos[2]:
if ballPos[3] >= racketPos[1] and ballPos[3] <= racketPos[3]:
return True
return False
def ballMove(self):
self.canvas.move(self.id, self.x, self.y)
ballPos = self.canvas.coords(self.id)
if ballPos[0] <= 0:
self.x = step
if ballPos[1] <= 0:
self.y = step
if ballPos[2] >= winW:
self.x = -step
if self.hitRacket(ballPos) == True:
self.y = -step
if ballPos[3] >= winH:
self.notTouchBottom = False
这个球类有三个方法,初始化,击中挡板和移动
初始化方法里主要定义小球以及将挡板引入(方便判断碰撞事件),还初定义了球的移动
击中挡板方法里定义了小球与挡板的碰撞事件,将在后续代码里处理
移动方法则定义了小球的移动,以及与窗口边缘触碰后发生的事件
定义挡板类
class Racket:
def __init__(self, canvas, color):
self.canvas = canvas
self.id = canvas.create_rectangle(0, 0, 100, 15, fill=color)
self.canvas.move(self.id, 270, 400)
self.x = 0
self.canvas.bind_all('<KeyPress-Right>', self.moveRight)
self.canvas.bind_all('<KeyPress-Left>', self.moveLeft)
def racketMove(self):
self.canvas.move(self.id, self.x, 0)
racketPos = self.canvas.coords(self.id)
if racketPos[0] <= 0:
self.x = 0
elif racketPos[2] >= winW:
self.x = 0
def moveLeft(self, event):
self.x = -3
def moveRight(self, event):
self.x = 3
挡板类有四个方法,初始化方法,挡板移动方法,向左和向右方法
初始化方法定义了挡板的基础数值和监听键盘按下左和右的事件
挡板移动方法则处理了当挡板超过窗口边界发生的事
向左向右方法顾名思义
定义窗口大小等参数
winW = 640
winH = 480
step = 3
speed = 0.01
定义了高度宽度,步长,速度
对象实例化
tk = Tk()
tk.title("Bouncing Ball")
tk.wm_attributes('-topmost', 1)
canvas = Canvas(tk, width=winW, height=winH)
canvas.pack()
tk.update()
racket = Racket(canvas, 'purple')
ball = Ball(canvas, 'yellow', winW, winH, racket)
创建窗口并且给球和挡板类创建实例化对象
循环监听事件
while ball.notTouchBottom:
try:
ball.ballMove()
except:
print("单击关闭按钮终止程序执行")
break
racket.racketMove()
tk.update()
time.sleep(speed)
我们创建循环以便监听按键,退出游戏等事件
最终代码和最终效果
最终代码
from tkinter import *
from random import *
import time
class Ball:
def __init__(self, canvas, color, winW, winH, racket):
self.canvas = canvas
self.racket = racket
self.id = canvas.create_oval(0, 0, 20, 20, fill=color)
self.canvas.move(self.id, winW/2, winH/2)
startPos = [-4, -3, -2, -1, 1, 2, 3, 4]
shuffle(startPos)
self.x = startPos[0]
self.y = -step
self.notTouchBottom= True
def hitRacket(self, ballPos):
racketPos = self.canvas.coords(self.racket.id)
if ballPos[2] >= racketPos[0] and ballPos[0] <= racketPos[2]:
if ballPos[3] >= racketPos[1] and ballPos[3] <= racketPos[3]:
return True
return False
def ballMove(self):
self.canvas.move(self.id, self.x, self.y)
ballPos = self.canvas.coords(self.id)
if ballPos[0] <= 0:
self.x = step
if ballPos[1] <= 0:
self.y = step
if ballPos[2] >= winW:
self.x = -step
if self.hitRacket(ballPos) == True:
self.y = -step
if ballPos[3] >= winH:
self.notTouchBottom = False
class Racket:
def __init__(self, canvas, color):
self.canvas = canvas
self.id = canvas.create_rectangle(0, 0, 100, 15, fill=color)
self.canvas.move(self.id, 270, 400)
self.x = 0
self.canvas.bind_all('<KeyPress-Right>', self.moveRight)
self.canvas.bind_all('<KeyPress-Left>', self.moveLeft)
def racketMove(self):
self.canvas.move(self.id, self.x, 0)
racketPos = self.canvas.coords(self.id)
if racketPos[0] <= 0:
self.x = 0
elif racketPos[2] >= winW:
self.x = 0
def moveLeft(self, event):
self.x = -3
def moveRight(self, event):
self.x = 3
winW = 640
winH = 480
step = 3
speed = 0.01
tk = Tk()
tk.title("Bouncing Ball")
tk.wm_attributes('-topmost', 1)
canvas = Canvas(tk, width=winW, height=winH)
canvas.pack()
tk.update()
racket = Racket(canvas, 'purple')
ball = Ball(canvas, 'yellow', winW, winH, racket)
while ball.notTouchBottom:
try:
ball.ballMove()
except:
print("单击关闭按钮终止程序执行")
break
racket.racketMove()
tk.update()
time.sleep(speed)
最终效果
如果对你有帮助麻烦点个赞吧