项目简介
本项目报名参加了“兖州中材杯”武汉理工大学第十一届环保创意作品大赛艺术理念组比赛。组员共三名,本人负责代码实现部分,其余两人分别负责项目策划与场景人物绘制。
项目背景
小组中负责策划的同学经过一定的调研之后发现,我校在校学生普遍缺乏垃圾分类方面的知识。经过讨论后,我们把游戏方向定位于“垃圾分类”,游戏类型定位于像素风游戏,由于本人水平和时间有限,只能将玩法设计得尽量简单。感谢另外两位组员,他们的努力掩盖了我水平上的不足。
玩法介绍
家控制一名角色在操场背景上移动,垃圾桶在操场边上。捡起垃圾丢进相应的垃圾桶内,若全部正确投放则游戏成功,否则游戏失败。游戏期间,若有不清楚该作何分类的垃圾,则可以点击图书馆的按钮,进入图书馆查询。图书馆提供垃圾图鉴和分类标准两种信息。垃圾图鉴帮助玩家分辨自己捡到的垃圾,而分类标准指每种垃圾的定义及举例。
项目成果
本项目在“兖州中材杯”武汉理工大学第十一届环保创意作品大赛艺术理念组比赛中最终获得了第五名、二等奖的成绩,距第四名仅差0.5分。
项目实现
写项目时本人仅自学了一个月的Python,且本人是大一新生,对计算机科学的基础知识了解甚少,若代码风格幼稚、愚蠢,还望读者见谅。
模块划分
游戏按场景分为以下几个模块:开始游戏界面、游戏说明界面、人物选择界面、操场界面(主要游戏场地)、图书馆外界面、图书馆内界面、游戏结束界面。
- 开始游戏界面:背景(像素化的学校建筑),游戏标题,三个按钮(开始、游戏说明、退出)。
![bca40fbde182b9535af46533d0214844.png](https://i-blog.csdnimg.cn/blog_migrate/be4702e4cc543d83930155053e49da69.jpeg)
- 游戏说明界面:背景(与开始界面相同),游戏说明文字,返回按钮。
![8b1877a43395d7319a8cbd6d18055fa6.png](https://i-blog.csdnimg.cn/blog_migrate/1d76c6f5d2d888bea23aaf56e4f8c2bd.jpeg)
- 人物选择界面:背景,提示(选择人物),两个可选人物。
![60c8159e48cc040abecff87e46b399ce.png](https://i-blog.csdnimg.cn/blog_migrate/82994804495a334f63146c9a7762b681.jpeg)
- 操场界面:背景,人物,垃圾桶,随机产生的垃圾,图书馆按钮。
![82663273a21b130d7f2adffbcdf58b38.png](https://i-blog.csdnimg.cn/blog_migrate/c4c3838620e63331498e890bbb2583d8.jpeg)
![44d044e3741f924077f2e90587fdb096.png](https://i-blog.csdnimg.cn/blog_migrate/1e0a2fe2f66868a89f418c698af46bc0.jpeg)
图书馆外界面:背景(我校图书馆的像素风绘制)、操场按钮(会到操场)、进入按钮(进入图书馆内部)。
![66fd3cae0851250b2d1952052ca9e5df.png](https://i-blog.csdnimg.cn/blog_migrate/f888a5e5a8d1171d801b2143d1b5a984.jpeg)
图书馆内界面:背景(我校图书馆内部),各类垃圾图标按钮(厨余垃圾、可回收垃圾、有害垃圾、其他垃圾),垃圾图鉴按钮,返回按钮。子界面:各类垃圾信息界面,垃圾图鉴界面,返回按钮。
![f954bf03001c3a85121bc6ab4202fb2c.png](https://i-blog.csdnimg.cn/blog_migrate/0cca98177d20760bea3a88f52fb02607.jpeg)
![7cf84f7b491ce551a40e9197b850052b.png](https://i-blog.csdnimg.cn/blog_migrate/4bf214faeb6080233df253d643188bc5.jpeg)
![b4b5243a14ed08a815d2140f33474563.png](https://i-blog.csdnimg.cn/blog_migrate/4d8e3ea8ebeb43114979a90be5633863.jpeg)
![230ca74eb012f0423a4c8487b85c0a70.png](https://i-blog.csdnimg.cn/blog_migrate/98ce36480ca987d895e25d34c62ae2ee.jpeg)
![03d00f7771ca6f80544bf2ee752eb900.png](https://i-blog.csdnimg.cn/blog_migrate/780937bef6cb0296bfa5e9924d021999.jpeg)
![985a98df2bfeb4362a936d7f3ca5497e.png](https://i-blog.csdnimg.cn/blog_migrate/1607bf2f8b36924ae439313405208bf3.jpeg)
游戏结束界面:胜利界面,失败界面。
![8d9978d44c52f0745d7301a0a4e9257f.png](https://i-blog.csdnimg.cn/blog_migrate/17123402026a860ac951b13585fc9c3b.jpeg)
![5ff1155373b9de2c177fe993b961eca7.png](https://i-blog.csdnimg.cn/blog_migrate/746b701326909b07963769f3c99a7d31.png)
代码实现
直接上代码:
import pygame as py
import sys
import random
from pygame.locals import *
#===========================================================
#========================前期准备===========================
py.init()
#注:游戏需要的所有文件(图片等)都放在同游戏目录的"Files"目录下。
#定义一个按钮类
class Button(py.rect.Rect):
def __init__(self, obj):
super().__init__(obj)
def has(self, pos):
if self.right >= pos[0] >= self.left and self.bottom >= pos[1] >= self.top:
return True
else:
return False
screen = py.display.set_mode((1000, 650))
#===========================================================
#=========================图书馆内==========================
def knowledge(selection):
path = 'Filesinside_liberaryknowledge' + str(selection) + '.jpg'
know = py.image.load(path)
know = py.transform.smoothscale(know,(1000,650))
screen.blit(know,(0,0))
exits = py.image.load('Filesinside_liberaryback.png')
exits = py.transform.smoothscale(exits,(72,72))
exit_button = screen.blit(exits,(918, 570))
exit_button = Button(exit_button)
py.display.flip()
#进入事件循环
while True:
for event in py.event.get():
if event.type == QUIT:
sys.exit()
if event.type == MOUSEBUTTONDOWN:
pos = py.mouse.get_pos()
#点击离开该页面
if exit_button.has(pos):
selection = 0
break
if not selection:
break
def inside_Liberary():
ilib = py.image.load('Filesinside_liberaryInside.jpg')
ilib = py.transform.smoothscale(ilib,(1000,650))
screen.blit(ilib,(0,0))
#退出图书馆的按钮
exits = py.image.load('Filesinside_liberaryexit.png')
exits = py.transform.smoothscale(exits,(72,81))
exit_button = screen.blit(exits,(5, 560))
exit_button = Button(exit_button)
#厨余垃圾按钮
rubbish1 = py.image.load('Filesinside_liberaryrubbish1.png')
rubbish1 = py.transform.smoothscale(rubbish1,(150,298))
rubbish1_button = screen.blit(rubbish1, (80,150))
rubbish1_button = Button(rubbish1_button)
#可回收垃圾按钮
rubbish2 = py.image.load('Filesinside_liberaryrubbish2.png')
rubbish2 = py.transform.smoothscale(rubbish2,(150,298))
rubbish2_button = screen.blit(rubbish2, (310,150))
rubbish2_button = Button(rubbish2_button)
#有害垃圾按钮
rubbish3 = py.image.load('Filesinside_liberaryrubbish3.png')
rubbish3 = py.transform.smoothscale(rubbish3,(150,298))
rubbish3_button = screen.blit(rubbish3, (540,150))
rubbish3_button = Button(rubbish3_button)
#不可回收垃圾按钮
rubbish4 = py.image.load('Filesinside_liberaryrubbish4.png')
rubbish4 = py.transform.smoothscale(rubbish4,(150,298))
rubbish4_button = screen.blit(rubbish4, (770,150))
rubbish4_button = Button(rubbish4_button)
#图鉴按钮
rubbish5 = py.image.load('Filesinside_liberaryrubbish5.png')
rubbish5 = py.transform.smoothscale(rubbish5,(82, 72))
rubbish5_button = screen.blit(rubbish5, (903,560))
rubbish5_button = Button(rubbish5_button)
py.display.flip()
selection = -1
#进入事件循环
while True:
for event in py.event.get():
if event.type == QUIT:
sys.exit()
if event.type == MOUSEBUTTONDOWN:
pos = py.mouse.get_pos()
#点击离开图书馆
if exit_button.has(pos):
selection = 0
break
#点击厨余垃圾
if rubbish1_button.has(pos):
selection = 1
break
#点击可回收垃圾
if rubbish2_button.has(pos):
selection = 2
break
#点击有害垃圾
if rubbish3_button.has(pos):
selection = 3
break
#点击不可回收垃圾
if rubbish4_button.has(pos):
selection = 4
break
#点击图鉴
if rubbish5_button.has(pos):
selection = 5
break
if selection != -1:
break
if selection:
knowledge(selection)
inside_Liberary()
#===========================================================
#=========================图书馆外==========================
def outside_Liberary():
olib = py.image.load('Filesoutside_liberaryOutside.jpg')
olib = py.transform.smoothscale(olib,(1000,650))
screen.blit(olib,(0,0))
#进入图书馆的按钮
enter = py.image.load('Filesoutside_liberaryenter_lib.png')
enter = py.transform.smoothscale(enter,(72, 72))
enter_button = screen.blit(enter,(470,550))
enter_button = Button(enter_button)
#退出图书馆的按钮
exits = py.image.load('Filesoutside_liberaryplayground.png')
exits = py.transform.smoothscale(exits,(72, 51))
exit_button = screen.blit(exits,(5, 590))
exit_button = Button(exit_button)
py.display.flip()
selection = -1
#进入事件循环
while True:
for event in py.event.get():
if event.type == QUIT:
sys.exit()
if event.type == MOUSEBUTTONDOWN:
pos = py.mouse.get_pos()
#点击返回操场
if exit_button.has(pos):
selection = 0
break
#点击进入图书馆
if enter_button.has(pos):
selection = 1
break
if selection != -1:
break
if selection:
inside_Liberary()
outside_Liberary()
#===========================================================
#==========================游戏帮助=========================
def help_page():
background = py.image.load('Fileshelpbackground.jpg')
background = py.transform.smoothscale(background,(1000,650))
screen.blit(background,(0,0))
#返回按钮
exits = py.image.load('Fileshelpback.png')
exits = py.transform.smoothscale(exits,(72,57))
exit_button = screen.blit(exits,(5, 585))
exit_button = Button(exit_button)
py.display.flip()
back = 0
while True:
for event in py.event.get():
if event.type == QUIT:
sys.exit()
if event.type == MOUSEBUTTONDOWN:
pos = py.mouse.get_pos()
if exit_button.has(pos):
back = 1
break
if back:
break
#===========================================================
#==========================游戏结束=========================
def game_over(result):
path = 'Filesgame_overresult' + str(result) + '.png'
background = py.image.load(path)
background = py.transform.smoothscale(background,(1000,650))
screen.blit(background,(0,0))
py.display.flip()
temp = 0
while True:
for event in py.event.get():
if event.type == QUIT:
sys.exit()
if event.type == MOUSEBUTTONDOWN:
temp = 1
break
if temp:
break
#===========================================================
#==========================操场环节=========================
choices = ['01', '02', '11', '12', '21', '22', '31']
class Rubbish():
def __init__(self, sort):
self.sort = sort
self.img = py.image.load('Filesplayground' + sort + '.png')
x = random.randint(100, 1400)
y = random.randint(110, 900)
self.position = self.img.get_rect()
self.position = self.position.move((x, y))
screen.blit(self.img, self.position)
class Role():
def __init__(self, role):
self.r_side = py.image.load('Filesplayground' + role + '1.png')
self.r_walk = py.image.load('Filesplayground' + role + '2.png')
self.l_side = py.transform.flip(self.r_side, True, False)
self.l_walk = py.transform.flip(self.r_walk, True, False)
self.img = self. r_side
self.position = self.img.get_rect()
screen.blit(self.img, self.position)
self.rubbish = None
def move(self, key):
if key == K_UP:
if self.position.top <= 200:
return (0, 2)
else:
self.position = self.position.move(0, -2)
return 0
if key == K_DOWN:
if self.position.bottom >= 450:
return (0, -2)
else:
self.position = self.position.move(0, 2)
return 0
if key == K_RIGHT:
if self.position.right >= 800:
return (-2, 0)
else:
self.position = self.position.move(2, 0)
return 0
if key == K_LEFT:
if self.position.left <= 200:
return (2, 0)
else:
self.position = self.position.move(-2, 0)
return 0
class Trash_can():
def __init__(self, num):
self. num = num
self.img = py.image.load('Filesplayground' + str(num) + '.png')
self.img = py.transform.smoothscale(self.img,(100, 92))
self.position = self.img.get_rect()
self.position = self.position.move((100 + num*200, 0))
screen.blit(self.img, self.position)
def playground(selection):
background = py.image.load('FilesplaygroundPlayground.jpg')
screen.blit(background, [0, 0])
lib = py.image.load('Filesplaygroundliberary.png')
lib = py.transform.smoothscale(lib, (78, 72))
lib_button = screen.blit(lib, (900, 10))
lib_button = Button(lib_button)
trash_can = []
for num in range(0, 4):
trash_can.append(Trash_can(num))
role = Role(selection)
rubbish = []
for sort in choices:
rubbish.append(Rubbish(sort))
py.display.flip()
down = 0
go = None
move_bg = [0, 0]
temp = 0
while True:
for event in py.event.get():
if event.type == QUIT:
sys.exit()
if event.type == MOUSEBUTTONDOWN:
pos = py.mouse.get_pos()
if lib_button.has(pos):
outside_Liberary()
if event.type == KEYDOWN and
event.key in (K_UP, K_DOWN, K_RIGHT, K_LEFT):
if event.key == K_RIGHT:
role.img = role.r_side
elif event.key == K_LEFT:
role.img = role.l_side
down = 1
go = event.key
if event.type == KEYUP and event.key == go:
if event.key == K_RIGHT:
role.img = role.r_side
elif event.key == K_LEFT:
role.img = role.l_side
down = 0
take = role.position.collidelist([each.position for each in rubbish])
if take >= 0 and not role.rubbish:
role.rubbish = rubbish[take].sort[0]
del rubbish[take]
put = role.position.collidelist([each.position for each in trash_can])
if put >= 0 and role.rubbish:
if role.rubbish == str(trash_can[put].num):
role.rubbish = None
if not len(rubbish):
game_over(1)
break
else:
game_over(2)
break
if down:
moved = role.move(go)
temp += 1
if not temp % 20:
if role.img == role.r_side:
role.img = role.r_walk
elif role.img == role.r_walk:
role.img = role.r_side
elif role.img == role.l_side:
role.img = role.l_walk
else:
role.img = role.l_side
if moved:
if 0 >= moved[0] + move_bg[0] >= -497 and
0 >= moved[1] + move_bg[1] >= -326:
for i in range(2):
move_bg[i] += moved[i]
for each in rubbish:
each.position = each.position.move(moved)
for each in trash_can:
each.position = each.position.move(moved)
elif role.position.left - moved[0] >= 0 and
role.position.right - moved[0] <= 1000 and
role.position.top - moved[1] >= 0 and
role.position.bottom - moved[1] <= 650:
role. position = role.position.move([-i for i in moved])
screen.blit(background, move_bg)
lib = py.image.load('Filesplaygroundliberary.png')
lib = py.transform.smoothscale(lib, (78, 72))
lib_button = screen.blit(lib, (900, 10))
lib_button = Button(lib_button)
for each in trash_can:
screen.blit(each.img, each.position)
for each in rubbish:
screen.blit(each.img, each.position)
screen.blit(role.img, role.position)
py.display.flip()
#===========================================================
#==========================选择人物=========================
def choose_role():
background = py.image.load('Fileschoose_playerbackground.jpg')
background = py.transform.smoothscale(background,(1000,650))
screen.blit(background, (0, 0))
man = py.image.load('Fileschoose_playerman.png')
man = py.transform.smoothscale(man,(123, 325))
man_button = screen.blit(man,(200, 200))
man_button = Button(man_button)
woman = py.image.load('Fileschoose_playerwoman.png')
woman = py.transform.smoothscale(woman,(113, 325))
woman_button = screen.blit(woman,(687, 200))
woman_button = Button(woman_button)
py.display.flip()
while True:
for event in py.event.get():
if event.type == QUIT:
sys.exit()
if event.type == MOUSEBUTTONDOWN:
pos = py.mouse.get_pos()
if man_button.has(pos):
return 'man'
if woman_button.has(pos):
return 'woman'
#===========================================================
#========================开始游戏界面========================
def start():
background = py.image.load('Filesstartbackground.jpg')
background = py.transform.smoothscale(background,(1000,650))
screen.blit(background, (0, 0))
start_game = py.image.load('Filesstartstart_game.png')
start_game = py.transform.smoothscale(start_game,(140, 149))
start_button = screen.blit(start_game,(150, 330))
start_button = Button(start_button)
game_help = py.image.load('Filesstartgame_help.png')
game_help = py.transform.smoothscale(game_help,(280, 182))
help_button = screen.blit(game_help,(380, 320))
help_button = Button(help_button)
quit_game = py.image.load('Filesstartquit_game.png')
quit_game = py.transform.smoothscale(quit_game,(200,160))
quit_button = screen.blit(quit_game,(680, 330))
quit_button = Button(quit_button)
py.display.flip()
while True:
for event in py.event.get():
if event.type == QUIT:
sys.exit()
if event.type == MOUSEBUTTONDOWN:
pos = py.mouse.get_pos()
if start_button.has(pos):
role = choose_role()
playground(role)
break
elif help_button.has(pos):
help_page()
break
elif quit_button.has(pos):
sys.exit()
break
start()
start()
总结
这个游戏是本人第一次写出一百行以上的代码,写完后没来得及进行进一步的优化就提交了项目。写这篇博客作为我CSDN之路的第一步,也用以纪念此次参赛。各位大佬若有批评建议,欢迎在评论中指出,本人一定虚心改正。
原作者:Vincentish 如有侵权联系删除
更多案例教程源码 视频加群:1136192749