【6.5】弹球游戏
小时候应该都玩过弹球的游戏,下面的步骤就是如何用Python实现这个游戏
这是一个由反弹球和球拍构成的游戏,球会在屏幕上飞过来,玩家用球拍把它弹回去,如果球落在了屏幕底部,那么游戏就结束。
1.创建画布
from tkinter import *
import random
import time
tk=Tk()
tk.title("Game")
tk.resizable(0,0)
tk.wm_attributes("-topmost",1)
canvas=Canvas(tk,width=500,height=400,bd=0,highlightthickness=0)
canvas.pack()
tk.update()
注:
- tk.resizable(0,0),窗口大小在水平和垂直方向上都不能改变
- tk.wm_attributes("-topmost",1)把我们的画布窗口放在所有窗口之前
- bd=0,highlightthickness=0 画布之外没有边框
- tk.update() 初始化
2.创建球
在上面的代码
from tkinter import *
import random
import time
后面加上
class Ball:
def __init__(self,canvas,color):
self.canvas=canvas
self.id=canvas.create_oval(10,10,25,25,fill=color)
self.canvas.move(self.id,245,100)
def draw(self):
pass
>>> ball=Ball(canvas,'red')
就出现了一个红色的球
ball=Ball(canvas,'red')
while 1:
tk.update_idletasks()
tk.update()
time.sleep(0.01)
放在最上面的那段代码的后面
3.让小球移动
对Ball做一点修改
class Ball:
def __init__(self,canvas,color):
self.canvas=canvas
self.id=canvas.create_oval(10,10,25,25,fill=color)
self.canvas.move(self.id,245,100)
def draw(self):
self.canvas.move(self.id,0,-1)
对while做一点修改:
while 1:
ball.draw()
tk.update_idletasks()
tk.update()
time.sleep(0.01)
这个时候整个的代码应该是这样:
from tkinter import *
import random
import time
class Ball:
def __init__(self,canvas,color):
self.canvas=canvas
self.id=canvas.create_oval(10,10,25,25,fill=color)
self.canvas.move(self.id,245,100)
def draw(self):
self.canvas.move(self.id,0,-1)
tk=Tk()
tk.title("Game")
tk.resizable(0,0)
tk.wm_attributes("-topmost",1)
canvas=Canvas(tk,width=500,height=400,bd=0,highlightthickness=0)
canvas.pack()
tk.update()
ball=Ball(canvas,'red')
while 1:
ball.draw()
tk.update_idletasks()
tk.update()
time.sleep(0.01)
让小球来回反弹
class Ball:
def __init__(self,canvas,color):
self.canvas=canvas
self.id=canvas.create_oval(10,10,25,25,fill=color)
self.canvas.move(self.id,245,100)
self.x=0
self.y=-1
self.canvas_height=self.canvas.winfo_height()
def draw(self):
self.canvas.move(self.id,self.x,self.y)
pos=self.canvas.coords(self.id)
if pos[1]< =0:
self.y=1
if pos[3]>=self.canvas_height:
self.y=-1
注:self.canvas_height=self.canvas.winfo_height()获取画布的高度
pos=self.canvas.coords(self.id)获取对象的位置,为[x1,y1,x2,y2]分别对应左上角和右下角
改变小球的起始方向
class Ball:
def __init__(self,canvas,color):
self.canvas=canvas
self.id=canvas.create_oval(10,10,25,25,fill=color)
self.canvas.move(self.id,245,100)
starts=[-3,-2,-1,1,2,3]
random.shuffle(starts)
self.x=starts[0]
self.y=-3
self.canvas_height=self.canvas.winfo_height()
self.canvas_width=self.canvas.winfo_width()
def draw(self):
self.canvas.move(self.id,self.x,self.y)
pos=self.canvas.coords(self.id)
if pos[1]< =0:
self.y=3
if pos[3]>=self.canvas_height:
self.y=-3
if pos[0]< =0:
self.x=3
if pos[2]>=self.canvas_width:
self.x=-3
注:相当于在之前的基础上加了一个左右边界的限定
这个时候代码应该是这样的:
from tkinter import *
import random
import time
class Ball:
def __init__(self,canvas,color):
self.canvas=canvas
self.id=canvas.create_oval(10,10,25,25,fill=color)
self.canvas.move(self.id,245,100)
starts=[-3,-2,-1,1,2,3]
random.shuffle(starts)
self.x=starts[0]
self.y=-3
self.canvas_height=self.canvas.winfo_height()
self.canvas_width=self.canvas.winfo_width()
def draw(self):
self.canvas.move(self.id,self.x,self.y)
pos=self.canvas.coords(self.id)
if pos[1]< =0:
self.y=3
if pos[3]>=self.canvas_height:
self.y=-3
if pos[0]< =0:
self.x=3
if pos[2]>=self.canvas_width:
self.x=-3
tk=Tk()
tk.title("Game")
tk.resizable(0,0)
tk.wm_attributes("-topmost",1)
canvas=Canvas(tk,width=500,height=400,bd=0,highlightthickness=0)
canvas.pack()
tk.update()
ball=Ball(canvas,'red')
while 1:
ball.draw()
tk.update_idletasks()
tk.update()
time.sleep(0.01)
4.做一个球拍
在ball的draw函数后面新起一行
class Paddle:
def __init__(self,canvas,color):
self.canvas=canvas
self.id=canvas.create_rectangle(0,0,100,10,fill=color)
self.canvas.move(self.id,200,300)
def draw(self):
pass
修改后面的为
paddle=Paddle(canvas,'red')
ball=Ball(canvas,'red')
while 1:
ball.draw()
paddle.draw()
tk.update_idletasks()
tk.update()
time.sleep(0.01)
5.让球拍移动
class Paddle:
def __init__(self,canvas,color):
self.canvas=canvas
self.id=canvas.create_rectangle(0,0,100,10,fill=color)
self.canvas.move(self.id,200,300)
self.x=0
self.canvas_width=self.canvas.winfo_width()
self.canvas.bind_all('< KeyPress-Left>',self.turn_left)
self.canvas.bind_all('< KeyPress-Right>',self.turn_right)
def draw(self):
self.canvas.move(self.id,self.x,0)
pos=self.canvas.coords(self.id)
if pos[0]< =0:
self.x=0
if pos[2]>=self.canvas_width:
self.x=0
def turn_left(self,evt):
self.x=-2
def turn_right(self,evt):
self.x=2
6.判断小球是否碰到球拍
修改小球的init函数
class Ball:
def __init__(self,canvas,paddle,color):
self.canvas=canvas
self.paddle=paddle
self.id=canvas.create_oval(10,10,25,25,fill=color)
self.canvas.move(self.id,245,100)
starts=[-3,-2,-1,1,2,3]
random.shuffle(starts)
self.x=starts[0]
self.y=-3
self.canvas_height=self.canvas.winfo_height()
self.canvas_width=self.canvas.winfo_width()
def hit_paddle(self,pos):
paddle_pos=self.canvas.coords(self.paddle.id)
if pos[3]>=paddle_pos[1] and pos[2]>=paddle_pos[0] and pos[0]< =paddle_pos[2]:
return True
else:
return False
def draw(self):
self.canvas.move(self.id,self.x,self.y)
pos=self.canvas.coords(self.id)
if pos[1]< =0:
self.y=3
if pos[3]>=self.canvas_height:
self.y=-3
if pos[0]< =0:
self.x=3
if pos[2]>=self.canvas_width:
self.x=-3
if self.hit_paddle(pos)==True:
self.y=-3
修改
paddle=Paddle(canvas,'red')
ball=Ball(canvas,paddle,'red')
注:下面的这个函数主要是为了判断这个球是否在球拍上
def hit_paddle(self,pos):
paddle_pos=self.canvas.coords(self.paddle.id)
if pos[3]>=paddle_pos[1] and pos[2]>=paddle_pos[0] and pos[0]< =paddle_pos[2]:
return True
else:
return False
7.增加输赢因素
在ball的inif函数后面机上变量Hit_bottom
self.canvas_height=self.canvas.winfo_height()
self.canvas_width=self.canvas.winfo_width()
self.hit_bottom=False
对while出进行修改
while 1:
if ball.hit_bottom==False:
ball.draw()
paddle.draw()
tk.update_idletasks()
tk.update()
time.sleep(0.01)
修改ball的draw函数
if pos[3]>=self.canvas_height:
self.hit_bottom=True
8这个游戏的最终代码为:
from tkinter import *
import random
import time
class Ball:
def __init__(self,canvas,paddle,color):
self.canvas=canvas
self.paddle=paddle
self.id=canvas.create_oval(10,10,25,25,fill=color)
self.canvas.move(self.id,245,100)
starts=[-3,-2,-1,1,2,3]
random.shuffle(starts)
self.x=starts[0]
self.y=-3
self.canvas_height=self.canvas.winfo_height()
self.canvas_width=self.canvas.winfo_width()
self.hit_bottom=False
def hit_paddle(self,pos):
paddle_pos=self.canvas.coords(self.paddle.id)
if pos[3]>=paddle_pos[1] and pos[2]>=paddle_pos[0] and pos[0]< =paddle_pos[2]:
return True
else:
return False
def draw(self):
self.canvas.move(self.id,self.x,self.y)
pos=self.canvas.coords(self.id)
if pos[1]< =0:
self.y=3
if pos[3]>=self.canvas_height:
self.hit_bottom=True
if pos[0]< =0:
self.x=3
if pos[2]>=self.canvas_width:
self.x=-3
if self.hit_paddle(pos)==True:
self.y=-3
class Paddle:
def __init__(self,canvas,color):
self.canvas=canvas
self.id=canvas.create_rectangle(0,0,100,10,fill=color)
self.canvas.move(self.id,200,300)
self.x=0
self.canvas_width=self.canvas.winfo_width()
self.canvas.bind_all('< KeyPress-Left>',self.turn_left)
self.canvas.bind_all('< KeyPress-Right>',self.turn_right)
def draw(self):
self.canvas.move(self.id,self.x,0)
pos=self.canvas.coords(self.id)
if pos[0]< =0:
self.x=0
if pos[2]>=self.canvas_width:
self.x=0
def turn_left(self,evt):
self.x=-2
def turn_right(self,evt):
self.x=2
tk=Tk()
tk.title("Game")
tk.resizable(0,0)
tk.wm_attributes("-topmost",1)
canvas=Canvas(tk,width=500,height=400,bd=0,highlightthickness=0)
canvas.pack()
tk.update()
paddle=Paddle(canvas,'red')
ball=Ball(canvas,paddle,'red')
while 1:
if ball.hit_bottom==False:
ball.draw()
paddle.draw()
tk.update_idletasks()
tk.update()
time.sleep(0.01)
参考资料:
《趣学Python编程》
这里是一个广告位,,感兴趣的都可以发邮件聊聊:tiehan@sina.cn
个人公众号,比较懒,很少更新,可以在上面提问题,如果回复不及时,可发邮件给我: tiehan@sina.cn
个人公众号,比较懒,很少更新,可以在上面提问题,如果回复不及时,可发邮件给我: tiehan@sina.cn