趣学Python编程小测验参考答案(第十四章)
最近在自学python,颇多波折,查阅了很多资料,收货很大,在学到后几章,编写测验程序时,总是报错,想找个参考答案,总是找不到,只好自给自足了。经过反复尝试,总算是成功运行了,在这里分享给跟我一样的初学者,大神绕过。
一、游戏延时开始
1.第一种,按钮方式启动
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) #(10,10)左上角x,y坐标,(25,25)右下角x,y坐标,椭圆是鼠标点击左上角不放,拖动至右下角放开
self.canvas.move(self.id,245,100) #把椭圆移动至画布的中心
starts = [-3,-2,-1,1,2,3] #创建变量starts,它是一个由6组数字组成的列表
random.shuffle(starts) #用random.shuffle将starts列表混排
self.x = starts[0] #把列表中的第一个元素赋值给self.x
self.y = -3 #将self.y的值改为-3,让小球飞地快一点
self.canvas_height = self.canvas.winfo_height() #winfo_height()获取画布当前的高度,并把它赋值给对象变量self.canvas_height
self.canvas_width = self.canvas.winfo_width() #把画布的宽度赋值给变量self.canvas_width
self.hit_bottom = False
def hit_paddle(self,pos):
paddle_pos = self.canvas.coords(self.paddle.id) #把球拍当前位置信息赋值给paddle_pos(坐标列表)
if pos[2] >= paddle_pos[0] and pos[0] <= paddle_pos[2]:
if pos[3] >= paddle_pos[1] and pos[3] <= paddle_pos[3]: #两个if语句,判断球拍是否击中小球
return True
return False
def draw(self):
self.canvas.move(self.id,self.x,self.y)
pos = self.canvas.coords(self.id) #coords()返回画布上任何画好的东西的当前x,y坐标列表,即[x1,y1,x2,y2],(x1,y1)是椭圆左上角坐标,(x2,y2)是椭圆右下角坐标
if pos[1] <= 0: #判断y1(小球的顶部)是否小于等于0,球是否碰到画布顶部
self.y = 3 #是,则向下移动
if pos[3] >= self.canvas_height: #判断y2(小球的底部)是否大于等于画布的高度
self.hit_bottom = True
if self.hit_paddle(pos) == True: #判断小球底部是否碰到球拍,是,则反弹
self.y = -3
if pos[0] <= 0: #判断x1(小球的左侧)是否小于等于0,球是否碰到画布左侧
self.x = 3 #是,则向右移动
if pos[2] >= self.canvas_width: #判断x2(小球的右侧)是否大于等于画布宽度,球是否碰到画布右侧
self.x = -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 #球拍的起始位置为0
self.canvas_width = self.canvas.winfo_width() #把画布的宽度赋值给变量self.canvas_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 #球拍碰撞画布左侧,则停止移动
elif pos[2] >= self.canvas_width:
self.x = 0 #球拍碰撞画布右侧,则停止移动
def turn_left(self,evt):
self.x = -2 #球拍每次移动2个像素
def turn_right(self,evt):
self.x = 2
def start():
time.sleep(3) #开始执行start函数后,延时3秒运行
paddle = Paddle(canvas,'blue')
ball = Ball(canvas,paddle,'red')
while 1:
if ball.hit_bottom == False:
ball.draw()
paddle.draw()
tk.update_idletasks() #让tkinter快一点把画布上的东西画出来
tk.update()
time.sleep(0.01)
tk = Tk()
tk.title("game") #命名游戏窗口
tk.resizable(0,0) #画布大小不可调整,(0,0)代表窗口的大小在水平和垂直方向都不能改变
tk.wm_attributes("-topmost",1) #游戏窗口前段显示(-topmost)
canvas = Canvas(tk,width=500,height=400,bd=0,highlightthickness=0) #bd=0和highlightthickness=0确保在画布之外没有边框
canvas.pack() #让画布按前一行的宽度和高度参数来调整其自身大小
tk.update() #让tkinter为游戏做好初始化
btn = Button(tk,text='start',command=start) #创建一个start按钮,定义为当点击start按钮后,执行start函数
btn.pack( )
2.第二种,鼠标点击窗口方式启动
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) #(10,10)左上角x,y坐标,(25,25)右下角x,y坐标,椭圆是鼠标点击左上角不放,拖动至右下角放开
self.canvas.move(self.id,245,100) #把椭圆移动至画布的中心
starts = [-3,-2,-1,1,2,3] #创建变量starts,它是一个由6组数字组成的列表
random.shuffle(starts) #用random.shuffle将starts列表混排
self.x = starts[0] #把列表中的第一个元素赋值给self.x
self.y = -3 #将self.y的值改为-3,让小球飞地快一点
self.canvas_height = self.canvas.winfo_height() #winfo_height()获取画布当前的高度,并把它赋值给对象变量self.canvas_height
self.canvas_width = self.canvas.winfo_width() #把画布的宽度赋值给变量self.canvas_width
self.hit_bottom = False
def hit_paddle(self,pos):
paddle_pos = self.canvas.coords(self.paddle.id) #把球拍当前位置信息赋值给paddle_pos(坐标列表)
if pos[2] >= paddle_pos[0] and pos[0] <= paddle_pos[2]:
if pos[3] >= paddle_pos[1] and pos[3] <= paddle_pos[3]: #两个if语句,判断球拍是否击中小球
return True
return False
def draw(self):
self.canvas.move(self.id,self.x,self.y)
pos = self.canvas.coords(self.id) #coords()返回画布上任何画好的东西的当前x,y坐标列表,即[x1,y1,x2,y2],(x1,y1)是椭圆左上角坐标,(x2,y2)是椭圆右下角坐标
if pos[1] <= 0: #判断y1(小球的顶部)是否小于等于0,球是否碰到画布顶部
self.y = 3 #是,则向下移动
if pos[3] >= self.canvas_height: #判断y2(小球的底部)是否大于等于画布的高度
self.hit_bottom = True
if self.hit_paddle(pos) == True: #判断小球底部是否碰到球拍,是,则反弹
self.y = -3
if pos[0] <= 0: #判断x1(小球的左侧)是否小于等于0,球是否碰到画布左侧
self.x = 3 #是,则向右移动
if pos[2] >= self.canvas_width: #判断x2(小球的右侧)是否大于等于画布宽度,球是否碰到画布右侧
self.x = -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 #球拍的起始位置为0
self.canvas_width = self.canvas.winfo_width() #把画布的宽度赋值给变量self.canvas_width,为判断球拍是否碰撞画布边缘做准备
self.canvas.bind_all('<KeyPress-Left>',self.turn_left) #将键盘左方向键与球拍左移动作绑定
self.canvas.bind_all('<KeyPress-Right>',self.turn_right) #将键盘右方向键与球拍右移动作绑定
self.canvas.bind_all('<Button-1>',self.start) #将鼠标左键与start函数绑定,当点击鼠标左键时,调用start函数
def draw(self):
self.canvas.move(self.id,self.x,0)
pos = self.canvas.coords(self.id)
if pos[0] <= 0:
self.x = 0 #球拍碰撞画布左侧,则停止移动
elif pos[2] >= self.canvas_width:
self.x = 0 #球拍碰撞画布右侧,则停止移动
def turn_left(self,evt):
self.x = -2 #球拍每次移动2个像素
def turn_right(self,evt):
self.x = 2
def start(self,evt):
while 1: #将主循环放置于start函数之中,以实现鼠标点击后再开始游戏的目的
if ball.hit_bottom == False:
ball.draw()
paddle.draw()
tk.update_idletasks() #让tkinter快一点把画布上的东西画出来
tk.update()
time.sleep(0.01)
tk = Tk()
tk.title("game") #命名游戏窗口
tk.resizable(0,0) #画布大小不可调整,(0,0)代表窗口的大小在水平和垂直方向都不能改变
tk.wm_attributes("-topmost",1) #游戏窗口前段显示(-topmost)
canvas = Canvas(tk,width=500,height=400,bd=0,highlightthickness=0) #bd=0和highlightthickness=0确保在画布之外没有边框
canvas.pack() #让画布按前一行的宽度和高度参数来调整其自身大小
tk.update() #让tkinter为游戏做好初始化
paddle = Paddle(canvas,'blue')
ball = Ball(canvas,paddle,'red')
二、更好的“游戏结束”
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) #(10,10)左上角x,y坐标,(25,25)右下角x,y坐标,椭圆是鼠标点击左上角不放,拖动至右下角放开
self.canvas.move(self.id,245,100) #把椭圆移动至画布的中心
starts = [-3,-2,-1,1,2,3] #创建变量starts,它是一个由6组数字组成的列表
random.shuffle(starts) #用random.shuffle将starts列表混排
self.x = starts[0] #把列表中的第一个元素赋值给self.x
self.y = -3 #将self.y的值改为-3,让小球飞地快一点
self.canvas_height = self.canvas.winfo_height() #winfo_height()获取画布当前的高度,并把它赋值给对象变量self.canvas_height
self.canvas_width = self.canvas.winfo_width() #把画布的宽度赋值给变量self.canvas_width
self.hit_bottom = False
def hit_paddle(self,pos):
paddle_pos = self.canvas.coords(self.paddle.id) #把球拍当前位置信息赋值给paddle_pos(坐标列表)
if pos[2] >= paddle_pos[0] and pos[0] <= paddle_pos[2]:
if pos[3] >= paddle_pos[1] and pos[3] <= paddle_pos[3]: #两个if语句,判断球拍是否击中小球
return True
return False
def draw(self):
self.canvas.move(self.id,self.x,self.y)
pos = self.canvas.coords(self.id) #coords()返回画布上任何画好的东西的当前x,y坐标列表,即[x1,y1,x2,y2],(x1,y1)是椭圆左上角坐标,(x2,y2)是椭圆右下角坐标
if pos[1] <= 0: #判断y1(小球的顶部)是否小于等于0,球是否碰到画布顶部
self.y = 3 #是,则向下移动
if pos[3] >= self.canvas_height: #判断y2(小球的底部)是否大于等于画布的高度
self.hit_bottom = True
if self.hit_paddle(pos) == True: #判断小球底部是否碰到球拍,是,则反弹
self.y = -3
if pos[0] <= 0: #判断x1(小球的左侧)是否小于等于0,球是否碰到画布左侧
self.x = 3 #是,则向右移动
if pos[2] >= self.canvas_width: #判断x2(小球的右侧)是否大于等于画布宽度,球是否碰到画布右侧
self.x = -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 #球拍的起始位置为0
self.canvas_width = self.canvas.winfo_width() #把画布的宽度赋值给变量self.canvas_width,为判断球拍是否碰撞画布边缘做准备
self.canvas.bind_all('<KeyPress-Left>',self.turn_left) #将键盘左方向键与球拍左移动作绑定
self.canvas.bind_all('<KeyPress-Right>',self.turn_right) #将键盘右方向键与球拍右移动作绑定
self.canvas.bind_all('<Button-1>',self.start) #将鼠标左键与start函数绑定,当点击鼠标左键时,调用start函数
def draw(self):
self.canvas.move(self.id,self.x,0)
pos = self.canvas.coords(self.id)
if pos[0] <= 0:
self.x = 0 #球拍碰撞画布左侧,则停止移动
elif pos[2] >= self.canvas_width:
self.x = 0 #球拍碰撞画布右侧,则停止移动
def turn_left(self,evt):
self.x = -2 #球拍每次移动2个像素
def turn_right(self,evt):
self.x = 2
def start(self,evt):
while 1: #将主循环放置于start函数之中,以实现鼠标点击后再开始游戏的目的
if ball.hit_bottom == False:
ball.draw()
paddle.draw()
else:
time.sleep(1)
canvas.create_text(249,389,text='游戏结束',font=('Time',20),fill='red')
tk.update_idletasks() #让tkinter快一点把画布上的东西画出来
tk.update()
time.sleep(0.01)
tk = Tk()
tk.title("game") #命名游戏窗口
tk.resizable(0,0) #画布大小不可调整,(0,0)代表窗口的大小在水平和垂直方向都不能改变
tk.wm_attributes("-topmost",1) #游戏窗口前段显示(-topmost)
canvas = Canvas(tk,width=500,height=400,bd=0,highlightthickness=0) #bd=0和highlightthickness=0确保在画布之外没有边框
canvas.pack() #让画布按前一行的宽度和高度参数来调整其自身大小
tk.update() #让tkinter为游戏做好初始化
paddle = Paddle(canvas,'blue')
ball = Ball(canvas,paddle,'red')
三、让小球加速
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) #(10,10)左上角x,y坐标,(25,25)右下角x,y坐标,椭圆是鼠标点击左上角不放,拖动至右下角放开
self.canvas.move(self.id,245,100) #把椭圆移动至画布的中心
starts = [-3,-2,-1,1,2,3] #创建变量starts,它是一个由6组数字组成的列表
random.shuffle(starts) #用random.shuffle将starts列表混排
self.x = starts[0] #把列表中的第一个元素赋值给self.x
self.y = -3 #让小球飞地快一点
self.canvas_height = self.canvas.winfo_height() #winfo_height()获取画布当前的高度,并把它赋值给对象变量self.canvas_height
self.canvas_width = self.canvas.winfo_width() #把画布的宽度赋值给变量self.canvas_width
self.hit_bottom = False
def hit_paddle(self,pos):
paddle_pos = self.canvas.coords(self.paddle.id) #把球拍当前位置信息赋值给paddle_pos(坐标列表)
if pos[2] >= paddle_pos[0] and pos[0] <= paddle_pos[2]:
if pos[3] >= paddle_pos[1] and pos[3] <= paddle_pos[3]: #两个if语句,判断球拍是否击中小球
return True
return False
def draw(self):
self.canvas.move(self.id,self.x,self.y)
pos = self.canvas.coords(self.id) #coords()返回画布上任何画好的东西的当前x,y坐标列表,即[x1,y1,x2,y2],(x1,y1)是椭圆左上角坐标,(x2,y2)是椭圆右下角坐标
if pos[1] <= 0: #判断y1(小球的顶部)是否小于等于0,球是否碰到画布顶部
self.y = 3 #是,则向下移动
if pos[3] >= self.canvas_height: #判断y2(小球的底部)是否大于等于画布的高度
self.hit_bottom = True
if self.hit_paddle(pos) == True: #判断小球底部是否碰到球拍,是,则反弹
self.y = -(3+abs(paddle.x)) #将球拍的速度传递给小球,让其飞地更快
if pos[0] <= 0: #判断x1(小球的左侧)是否小于等于0,球是否碰到画布左侧
self.x = 3 #是,则向右移动
if pos[2] >= self.canvas_width: #判断x2(小球的右侧)是否大于等于画布宽度,球是否碰到画布右侧
self.x = -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 #球拍的起始位置为0
self.canvas_width = self.canvas.winfo_width() #把画布的宽度赋值给变量self.canvas_width,为判断球拍是否碰撞画布边缘做准备
self.canvas.bind_all('<KeyPress-Left>',self.turn_left) #将键盘左方向键与球拍左移动作绑定
self.canvas.bind_all('<KeyPress-Right>',self.turn_right) #将键盘右方向键与球拍右移动作绑定
self.canvas.bind_all('<Button-1>',self.start) #将鼠标左键与start函数绑定,当点击鼠标左键时,调用start函数
def draw(self):
self.canvas.move(self.id,self.x,0)
pos = self.canvas.coords(self.id)
if pos[0] <= 0:
self.x = 0 #球拍碰撞画布左侧,则停止移动
elif pos[2] >= self.canvas_width:
self.x = 0 #球拍碰撞画布右侧,则停止移动
def turn_left(self,evt):
self.x = -2 #球拍每次移动2个像素
def turn_right(self,evt):
self.x = 2
def start(self,evt):
while 1: #将主循环放置于start函数之中,以实现鼠标点击后再开始游戏的目的
if ball.hit_bottom == False:
ball.draw()
paddle.draw()
else:
time.sleep(1)
canvas.create_text(249,389,text='游戏结束',font=('Time',20),fill='red')
tk.update_idletasks() #让tkinter快一点把画布上的东西画出来
tk.update()
time.sleep(0.01)
tk = Tk()
tk.title("game") #命名游戏窗口
tk.resizable(0,0) #画布大小不可调整,(0,0)代表窗口的大小在水平和垂直方向都不能改变
tk.wm_attributes("-topmost",1) #游戏窗口前段显示(-topmost)
canvas = Canvas(tk,width=500,height=400,bd=0,highlightthickness=0) #bd=0和highlightthickness=0确保在画布之外没有边框
canvas.pack() #让画布按前一行的宽度和高度参数来调整其自身大小
tk.update() #让tkinter为游戏做好初始化
paddle = Paddle(canvas,'blue')
ball = Ball(canvas,paddle,'red')
四、记录玩家得分
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) #(10,10)左上角x,y坐标,(25,25)右下角x,y坐标,椭圆是鼠标点击左上角不放,拖动至右下角放开
self.canvas.move(self.id,245,100) #把椭圆移动至画布的中心
starts = [-3,-2,-1,1,2,3] #创建变量starts,它是一个由6组数字组成的列表
random.shuffle(starts) #用random.shuffle将starts列表混排
self.x = starts[0] #把列表中的第一个元素赋值给self.x
self.y = -3 #让小球飞地快一点
self.canvas_height = self.canvas.winfo_height() #winfo_height()获取画布当前的高度,并把它赋值给对象变量self.canvas_height
self.canvas_width = self.canvas.winfo_width() #把画布的宽度赋值给变量self.canvas_width
self.hit_bottom = False
self.score = 0 #将score作为Ball类中的一个变量进行初始化
def hit_paddle(self,pos):
paddle_pos = self.canvas.coords(self.paddle.id) #把球拍当前位置信息赋值给paddle_pos(坐标列表)
if pos[2] >= paddle_pos[0] and pos[0] <= paddle_pos[2]:
if pos[3] >= paddle_pos[1] and pos[3] <= paddle_pos[3]: #两个if语句,判断球拍是否击中小球
return True
return False
def draw(self):
canvas.itemconfig(my_score,text='得分:%s' %(self.score)) #使用itemconfig函数刷新得分
self.canvas.move(self.id,self.x,self.y)
pos = self.canvas.coords(self.id) #coords()返回画布上任何画好的东西的当前x,y坐标列表,即[x1,y1,x2,y2],(x1,y1)是椭圆左上角坐标,(x2,y2)是椭圆右下角坐标
if pos[1] <= 0: #判断y1(小球的顶部)是否小于等于0,球是否碰到画布顶部
self.y = 3 #是,则向下移动
if pos[3] >= self.canvas_height: #判断y2(小球的底部)是否大于等于画布的高度
self.hit_bottom = True
if self.hit_paddle(pos) == True: #判断小球底部是否碰到球拍,是,则反弹
self.y = -(3+abs(paddle.x)) #将球拍的速度传递给小球,让其飞地更快
self.score = self.score + 1 #球拍击中小球一次,加1分
if pos[0] <= 0: #判断x1(小球的左侧)是否小于等于0,球是否碰到画布左侧
self.x = 3 #是,则向右移动
if pos[2] >= self.canvas_width: #判断x2(小球的右侧)是否大于等于画布宽度,球是否碰到画布右侧
self.x = -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 #球拍的起始位置为0
self.canvas_width = self.canvas.winfo_width() #把画布的宽度赋值给变量self.canvas_width,为判断球拍是否碰撞画布边缘做准备
self.canvas.bind_all('<KeyPress-Left>',self.turn_left) #将键盘左方向键与球拍左移动作绑定
self.canvas.bind_all('<KeyPress-Right>',self.turn_right) #将键盘右方向键与球拍右移动作绑定
self.canvas.bind_all('<Button-1>',self.start) #将鼠标左键与start函数绑定,当点击鼠标左键时,调用start函数
def draw(self):
self.canvas.move(self.id,self.x,0)
pos = self.canvas.coords(self.id)
if pos[0] <= 0:
self.x = 0 #球拍碰撞画布左侧,则停止移动
elif pos[2] >= self.canvas_width:
self.x = 0 #球拍碰撞画布右侧,则停止移动
def turn_left(self,evt):
self.x = -2 #球拍每次移动2个像素
def turn_right(self,evt):
self.x = 2
def start(self,evt):
while 1: #将主循环放置于start函数之中,以实现鼠标点击后再开始游戏的目的
if ball.hit_bottom == False:
ball.draw()
paddle.draw()
else:
time.sleep(1)
canvas.create_text(249,389,text='游戏结束',font=('Time',20),fill='red')
tk.update_idletasks() #让tkinter快一点把画布上的东西画出来
tk.update()
time.sleep(0.01)
tk = Tk()
tk.title("game") #命名游戏窗口
tk.resizable(0,0) #画布大小不可调整,(0,0)代表窗口的大小在水平和垂直方向都不能改变
tk.wm_attributes("-topmost",1) #游戏窗口前段显示(-topmost)
canvas = Canvas(tk,width=500,height=400,bd=0,highlightthickness=0) #bd=0和highlightthickness=0确保在画布之外没有边框
my_score = canvas.create_text(450,10,text='得分:%s' %(0),fill='blue') #在画布右上角绘制得分文本框
canvas.pack() #让画布按前一行的宽度和高度参数来调整其自身大小
tk.update() #让tkinter为游戏做好初始化
paddle = Paddle(canvas,'blue')
ball = Ball(canvas,paddle,'red')
基本每行代码都做了注释,便于程序小白理解