项目背景:
现在我们的校园、小区、公园甚至新农村都有垃圾分类站,垃圾分类已经成了我们日常生活的基本要求。我们今天就要学习如何来制作这样一个游戏。游戏的功能是要求游戏者要在规定的时间内将随机生成的垃圾按正确的方式进行分类,分类正确得分,最后统计你的最终得分。游戏界面如下图所示。
游戏效果图
项目分析:
要完成本项目需要学习三方库的安装、导入,pygame库的使用,具体看以下思维导图。
项目实施
三方库的安装与导入
操作步骤:
- 安装三方库pygame
- 导入相关库
#导入库
import random, sys,time
import pygame
from pygame.locals import *
【代码解析】三方库pygame的安装方法很多,最常用的方法是打开DOS界面,输入命令:pip install game。由于三方库官方的下载速度比较慢,那我们可以用命令 pip install game -i https://pypi.tuna.tsinghua.edu.cn/simple 这表示从国内清华大学的服务器安装,速度更快更方便。
任务2:初始化
窗口初始化
pygame.init() # pygame库初始化
size = (980, 540) # 设置size表示窗口宽度*高度
screen = pygame.display.set_mode(size) # 窗口设置
pygame.display.set_caption("垃圾分类 从我做起!") # 设置窗口标题栏
backbroud_Image_Filename = r'garbage_img/bg.png' # 设置背景图片路径变量
backgrooud = pygame.image.load(backbroud_Image_Filename) # 加载背景图片
代码解析】pygame 库主要用于开发游戏。它首先要进行初始化操作,建立最小框架的显示界面。主要是建立窗体对象如screen是pygaem下display的一个类并能设置窗体的大小和标题显示。如果显示有背景图片的窗体则通过load()加载指定的图片。
【代码解析】上图代码用于加载如下图片,用于在判断垃圾分类正确或错误时显示的图片。
接下去要设计各种垃圾图片,可以定义一个列表,列表元素每张垃圾图片,列表元素用字典来表示。每个字典包含两个键值对,第一个键值对用img:图片路径;第二个键值对用key:数值,其中0~3分别表示在害垃圾、可回收垃圾、易腐垃圾和其它垃圾。
正确图片
rightImage = pygame.image.load(r'garbage_img/right.png').convert_alpha()
错误图片
wrongImage = pygame.image.load(r'garbage_img/wrong.png').convert_alpha()
随机生成垃圾图片列表
position = size[0] // 2, size[1] // 2
garbage = [{'img': r'garbage_img/01.png', 'key': 2},{'img': r'garbage_img/02.png', 'key': 2},
{'img': r'garbage_img/03.png', 'key': 2},{'img': r'garbage_img/04.png', 'key': 1},
{'img': r'garbage_img/05.png', 'key': 2},{'img': r'garbage_img/06.png', 'key': 1},
{'img': r'garbage_img/07.png', 'key': 3},{'img': r'garbage_img/08.png', 'key': 0},
{'img': r'garbage_img/09.png', 'key': 3},{'img': r'garbage_img/10.png', 'key': 0},
{'img': r'garbage_img/11.png', 'key': 0},{'img': r'garbage_img/12.png', 'key': 1},
{'img': r'garbage_img/13.png', 'key': 1},{'img': r'garbage_img/14.png', 'key': 1},
{'img': r'garbage_img/15.png', 'key': 1},{'img': r'garbage_img/16.png', 'key': 1},
{'img': r'garbage_img/17.png', 'key': 2},{'img': r'garbage_img/18.png', 'key': 2},
{'img': r'garbage_img/19.png', 'key': 3},{'img': r'garbage_img/20.png', 'key': 3}, ]
生成随机垃圾图片编号
randomNum = random.randint(0, len(garbage) - 1)
【代码解析】变量position表示位置变量,初值是屏幕中心。建立garbage列表,将20张垃圾图片的值存入。变量randomNum表示随机图片的编号。
接下去要设计各种变量:
统计得分变量score
垃圾能否移动变量 moving
游戏能否运动变量 start
时间变量counts
自定义事件COUNT(事件名须大写)用于记录游戏时间也就是次数。
定义各种变量
score = 0 #得分变量
moving = False # 能否移动标记变量
start=True # 游戏能否运行标记变量
counts=30 # 时间变量
COUNT=pygame.USEREVENT+1 # 自定义事件
pygame.time.set_timer(COUNT,1000) # 设置时间周期
【代码解析】定义变量的语句组。USEREVENT指用户事件。
为了模块化编程,我们定义两个函数分别用于经常用到的功能:移动垃圾图片和显示文本信息。
任务3: 自定义函数
定义 移动垃圾图片函数
def move_garbageImg():
x, y = pygame.mouse.get_pos()
pygame.mouse.set_visible(False)
screen.blit(garbageImg, (x, y))
定义显示文本的函数
def showText(text, x, y, size):
font1 = pygame.font.SysFont('SimHei', size)
screen.blit(font1.render(text, True, (0, 0, 0)), (x, y))
【代码解析】在定义garbageImg()是一个无参函数,其语句功能分别是获取鼠标的坐标(x,y),并隐藏光标。Blit()函数是screen类的一个实例,其功能是在某坐标处显示图片对象。有两个参数分别表示显示的对象和坐标。自定义函数showText()是一个有参函数,设计的四个参数text表示要显示的文本内容、x和y表示坐标,size表示文字大小。
在完成以上工作后,重点是主循环的编写。该部分内容主要功能监控时间变量,只要在规定的时间内保持循环,使整个游戏能一直运行。循环体包括监控键盘事件、判断垃圾分类是否正确及得分等。
任务4: 主程序部分WHILE循环
当循环 保持运行
while True:
for event in pygame.event.get():
if event.type == QUIT:
pygame.quit()
sys.exit()
if event.type == pygame.MOUSEBUTTONDOWN:
if event.button == 1:
moving = True
if event.type == pygame.MOUSEBUTTONUP:
if event.button == 1:
moving = False
if moving == True:
position = pygame.mouse.get_pos()
move_garbageImg()
if event.type==COUNT:
if start==True:
counts-=1
if counts<=0:
start=False
if start==True:
# 判断垃圾桶纵坐标位置范围
move_garbageImg()
if position[1] >= 380 and position[1] <= 500:
# 可有害垃圾水平坐标范围
if position[0] >= 115 and position[0] <= 215:
if garbage[randomNum]['key'] == 0:
score += 5
screen.blit(rightImage, (450, 130))
else:
screen.blit(wrongImage, (450, 130))
pygame.display.flip()
randomNum = random.randint(0, len(garbage) - 1)
position = size[0] // 2, size[1] // 2
moving = False
time.sleep(0.5)
elif position[0] >= 315 and position[0] <= 415:
if garbage[randomNum]['key'] == 1:
score += 5
screen.blit(rightImage, (450, 130))
else:
screen.blit(wrongImage, (450, 130))
pygame.display.flip()
randomNum = random.randint(0, len(garbage) - 1)
position = size[0] // 2, size[1] // 2
moving = False
time.sleep(0.5)
elif position[0] >= 530 and position[0] < 630:
if garbage[randomNum]['key'] == 2:
score += 5
screen.blit(rightImage, (450, 130))
else:
screen.blit(wrongImage, (450, 130))
pygame.display.flip()
randomNum = random.randint(0, len(garbage) - 1)
position = size[0] // 2, size[1] // 2
moving = False
time.sleep(0.5)
elif position[0] >= 730 and position[0] <= 830:
if garbage[randomNum]['key'] == 3:
score += 5
screen.blit(rightImage, (450, 130))
else:
screen.blit(wrongImage, (450, 130))
pygame.display.flip()
randomNum = random.randint(0, len(garbage) - 1)
position = size[0] // 2, size[1] // 2
moving = False
time.sleep(0.5)
if start:
screen.blit(backgrooud, (0, 0))
garbageImg = pygame.image.load(garbage[randomNum]['img']).convert_alpha()
move_garbageImg()
showText("剩下时间:"+str(counts),20,20,25)
showText("当前得分:"+str(score),20,60,25)
pygame.display.update()
else:
screen.blit(backgrooud, (0, 0))
showText("游戏结束,最终得分:" + str(score), 300, 180, 40)
pygame.display.update()