前提
要确保代码能运行,请确认你安装了相关的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)
最终效果
如果对你有帮助麻烦点个赞吧