找回密码
 会员注册
查看: 11|回复: 0

Python开心消消乐

[复制链接]

5

主题

0

回帖

16

积分

新手上路

积分
16
发表于 2024-9-7 20:53:34 | 显示全部楼层 |阅读模式
📒文章目录效果图项目结构程序代码完整代码:https://gitcode.com/stormsha1/games/overview效果图项目结构程序代码run.pyimportsysimportpygamefrompygame.localsimportKEYDOWN,QUIT,K_q,K_ESCAPE,MOUSEBUTTONDOWNfromdissipate.levelimportManagerfromdissipate.level_treeimportLevelTreeManagerfromdissipate.soundsimportSoundsclassGame:"""游戏主类,负责初始化和主循环"""def__init__(self):"""初始化游戏"""pygame.init()pygame.mixer.init()pygame.display.set_caption('开心消消乐')#设置游戏窗口pygame.mouse.set_visible(False)#隐藏鼠标指针#初始化游戏管理器和声音self.tree=LevelTreeManager()#树管理器,用于主菜单self.manager=Manager(0,0)#游戏管理器,用于处理游戏逻辑self.world_bgm=pygame.mixer.Sound(Sounds.WORLD_BGM.value)#世界背景音乐self.game_bgm=pygame.mixer.Sound(Sounds.GAME_BGM.value)#游戏背景音乐#提高游戏性能的优化self.get_events=pygame.event.get#获取事件的方法self.update_window=pygame.display.flip#刷新窗口的方法self.sound_sign=0#用于控制背景音乐切换的标志defrun(self):"""主游戏循环"""whileTrue:self.handle_music()#处理背景音乐self.draw()#绘制游戏界面self.handle_events()#处理用户输入事件self.update()#更新显示defhandle_music(self):"""根据游戏级别管理背景音乐"""ifself.manager.level==0:ifself.sound_sign==0:self.game_bgm.stop()#停止游戏背景音乐self.world_bgm.play(-1)#循环播放世界背景音乐self.sound_sign=1else:ifself.sound_sign==1:self.world_bgm.stop()#停止世界背景音乐self.game_bgm.play(-1)#循环播放游戏背景音乐self.sound_sign=0defdraw(self):"""根据级别绘制相应的游戏界面"""ifself.manager.level==0:self.tree.draw_tree(self.manager.energy_num,self.manager.money)#绘制主菜单界面else:self.manager.set_level_mode(self.manager.level)#设置当前关卡模式sprite_group=self.manager.draw()#绘制游戏关卡界面ifself.manager.type==0:self.manager.eliminate_animals()#消除动物self.manager.death_map()#更新死亡地图self.manager.swap(sprite_group)#处理交换逻辑self.manager.judge_level()#判断关卡状态defhandle_events(self):"""处理用户输入事件"""foreventinself.get_events():ifevent.type==KEYDOWN:ifevent.keyin(K_q,K_ESCAPE):sys.exit()#按下Q或ESC键退出游戏elifevent.type==QUIT:sys.exit()#点击关闭按钮退出游戏elifevent.type==MOUSEBUTTONDOWN:mouse_x,mouse_y=event.pos#获取鼠标点击位置ifself.manager.level==0:self.tree.mouse_select(self.manager,mouse_x,mouse_y,self.manager.level,self.manager.energy_num,self.manager.money)#处理主菜单鼠标选择self.manager.mouse_select(mouse_x,mouse_y)#处理游戏内鼠标选择defupdate(self):"""更新鼠标图像并刷新显示:return:"""self.manager.mouse_image()#更新鼠标图像self.update_window()#刷新显示if__name__=='__main__':game=Game()#创建游戏实例game.run()#启动游戏12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697level.pyimportosfromrandomimportrandintimportpygamefrompygame.localsimport*frompygame.timeimportdelayfromdissipate.imgimportimg_basicfromdissipate.soundsimportSounds,play_soundfromdissipate.spritesimportBoard,ElementclassManager:"""Gamemanager."""#游戏屏幕的大小设置为900x600像素__screen_size=(900,600)#使用pygame库设置屏幕模式,DOUBLEBUF是双缓冲,32是位深度screen=pygame.display.set_mode(__screen_size,DOUBLEBUF,32)#砖块的大小设置为50x50像素__brick_size=50#加载背景图片并转换为优化格式__bg=pygame.image.load(os.path.join(img_basic,'bg.png')).convert()#停止宽度,可能用于游戏结束或暂停的界面stop_width=63#当前选中的砖块位置,格式为[row,col]selected=[-1,-1]#交换标志,可能用于交换砖块或游戏逻辑swap_sign=-1#上一次选中的砖块位置,格式为[row,col]last_sel=[-1,-1]#是否交换的标志,用于判断是否发生了交换value_swapped=False#死亡地图的标志,可能用于显示或隐藏死亡相关的游戏元素death_sign=True#消除4个砖块时选中的位置,格式为[row,col]boom_sel=[-1,-1]#当前关卡,0表示树(可能是特殊关卡或菜单)level=0#玩家的金钱数量money=100#能量点数energy_num=30#数字标志,可能用于显示或隐藏数字相关的游戏元素num_sign=True#游戏类型,0为进行中,1为通过,-1为失败,2为树type=2#是否重置布局的标志reset_mode=True#每个关卡的初始步数init_step=15#当前游戏剩余的步数step=init_step#玩家的得分score=0#中等得分的两个阈值min=20max=50#已消除动物的数量列表,长度为6,可能代表6种不同的动物animal_num=[0,0,0,0,0,0]#剩余需要消除的冰块数量ice_num=0#成功板,继承自Board类,位置在[200,0]success_board=Board(Board.success,[200,0])#失败板,继承自Board类,位置在[200,0]fail_board=Board(Board.fail,[200,0])#游戏网格的高度和宽度,都是9height,width=9,9#选中的行和列,初始值为5row,col=5,5#冰块列表,21x21的二维列表,-1表示无冰块,1表示有冰块ice_list=[[-1for_inrange(21)]for_inrange(21)]#动物列表,21x21的二维列表,-2表示已消除,-1表示无动物,0-4表示不同的动物animal=[[-1for_inrange(21)]for_inrange(21)]#砖块的x和y位置列表,用于确定砖块在屏幕上的位置list_x,list_y=(__screen_size[0]-11*__brick_size)/2,(__screen_size[1]-11*__brick_size)/2def__init__(self,width,height):self.height=heightself.width=widthself.list_x=(Manager.__screen_size[0]-self.width*Manager.__brick_size)/2self.list_y=(Manager.__screen_size[1]-self.height*Manager.__brick_size)/2self.row,self.col=Manager.xy_rc(self.list_x,self.list_y)self.list_x,self.list_y=Manager.rc_xy(self.row,self.col)self.ice_list=[[-1for_inrange(21)]for_inrange(21)]self.animal=[[-1for_inrange(21)]for_inrange(21)]self.reset_animals()defreset_animals(self):"""用于将游戏板上的动物随机重置为0到5之间的数字,其中0可能表示没有动物,1到5表示不同类型的动物。"""#遍历由self.row和self.col确定的起始行和列,直到高度和宽度决定的结束行和列forrowinrange(self.row,self.row+self.height):#对于每一行row,遍历由self.col和self.col+self.width确定的起始列和结束列forcolinrange(self.col,self.col+self.width):#为当前位置(row,col)随机分配一个动物编号,编号范围从0到5#randint是random模块中的一个函数,用于生成一个指定范围内的随机整数self.animal[row][col]=randint(0,5)@staticmethoddefrc_xy(row,col):"""(row,col)->(x,y)"""returnint(Manager.list_x+(col-Manager.col)*Manager.__brick_size),int\(Manager.list_y+(row-Manager.row)*Manager.__brick_size)@staticmethoddefxy_rc(x,y):"""(x,y)->(row,col)"""returnint((y-Manager.list_y)/Manager.__brick_size+Manager.row),int\((x-Manager.list_x)/Manager.__brick_size+Manager.col)@staticmethoddefdraw_brick(x,y):"""Drawabrickat(x,y)."""brick=Element(Element.brick,(x,y))Manager.screen.blit(brick.image,brick.rect)defdraw_task(self,task_animal_num,which_animal,board_position=(400,90),animal_position=(430,35),txt_position=(455,60)):"""绘制任务板"""txt_size=24txt_color=(0,0,0)Board(Board.task_board,board_position).draw(self.screen)ifwhich_animal==6:task_animal=Element(Element.ice,animal_position)else:task_animal=Element(Element.animals[which_animal],animal_position)task_animal.image=pygame.transform.smoothscale(task_animal.image,(40,40))task_animal.draw(self.screen)ifwhich_animal==6:iftask_animal_num-self.ice_num=20:#20令人难以置信Sounds.score_level(4)Element(Element.score_level[4],(350,250)).draw(self.screen)pygame.display.flip()delay(500)returnself.value_swapped#返回交换值标记deffall_animal(self):"""动物下落动画。"""clock=pygame.time.Clock()position=[]ice_position=[]#收集需要下落的动物的位置foriinrange(self.row,self.row+self.height):forjinrange(self.col,self.col+self.width):ifself.animal[i][j]==-2:x,y=self.rc_xy(i,j)position.append((x,y))ifself.ice_list[i][j]==1:ice_position.append((x,y))#下落动画ifposition:forindexinrange(0,9):clock.tick(20)forposinposition:self.draw_brick(pos[0],pos[1])ifposinice_position:Element(Element.ice_format%index,(pos[0],pos[1])).draw(self.screen)Element(Element.boom_format%index,(pos[0],pos[1])).draw(self.screen)pygame.display.flip()#实现下落foriinrange(self.row,self.row+self.height):brick_position=[]fall_animal_list=[]speed=[0,1]#收集需要下落的动物的位置信息forjinrange(self.col,self.col+self.width):ifself.animal[i][j]==-2:x,y=self.rc_xy(i,j)ifself.ice_list[i][j]==1:play_sound(Sounds.ICE_BREAKING)self.ice_num+=1self.ice_list[i][j]=-1brick_position.append((x,y))#收集需要下落的动物的信息forminrange(i,self.row-1,-1):ifself.animal[m-1][j]!=-1:x,y=self.rc_xy(m-1,j)brick_position.append((x,y))animal=Element(Element.animals[self.animal[m-1][j]],(x,y))fall_animal_list.append(animal)self.animal[m][j]=self.animal[m-1][j]else:self.animal[m][j]=randint(0,5)break#动物下落实现whilespeed!=[0,0]andfall_animal_list:forpositioninbrick_position:self.draw_brick(position[0],position[1])foranimal_spriteinfall_animal_list:animal_sprite.move(speed)animal_sprite.draw(self.screen)speed=animal_sprite.speedpygame.display.flip()defjudge_next(self,tp,score):"""判断是否达到下一关。"""iftp==1:#通过self.load_fns_window(score)eliftp==-1:#失败self.load_fail_window()defload_fail_window(self):"""显示失败界面和按钮。"""sound_sign=0step_add=Board(Board.step_add,Board.button_position[0])#左侧:再来5步retry=Board(Board.replay,Board.button_position[1])#右侧:重玩self.screen.blit(self.fail_board.image,self.fail_board.rect)#失败界面self.screen.blit(step_add.image,step_add.rect)self.screen.blit(retry.image,retry.rect)whileself.fail_board.speed!=[0,0]:self.draw()self.screen.blit(self.fail_board.image,self.fail_board.rect)self.fail_board.move()pygame.display.flip()ifsound_sign==0:play_sound(Sounds.BOARD_SOUND)sound_sign=1defload_fns_window(self,score):"""显示成功界面、分数和按钮。"""sound_sign=0replay=Board(Board.replay,Board.button_position[0])#左侧:重玩self.screen.blit(self.success_board.image,self.success_board.rect)#成功界面ifself.levelself.max:self.load_text('5',(Board.starts_position[1][0]+48,Board.starts_position[1][1]+35),20,(0,0,0))self.screen.blit(star1.image,star1.rect)self.screen.blit(star2.image,star2.rect)self.screen.blit(star3.image,star3.rect)pygame.display.flip()defset_level_mode(self,level):"""设置关卡模式及其步骤。"""self.level=levelifself.reset_mode:#如果需要重置模式self.num_sign=Trueiflevel==1:self.__init__(7,7)self.animal[7][9]=self.animal[7][10]=self.animal[7][11]=self.animal[8][10]=self.animal[11][7]=\self.animal[11][13]=self.animal[12][7]=self.animal[12][8]=self.animal[12][12]=\self.animal[12][13]=\self.animal[13][7]=self.animal[13][8]=self.animal[13][9]=self.animal[13][11]=\self.animal[13][12]=\self.animal[13][13]=-1self.init_step=17#初始步骤17eliflevel==2:self.__init__(4,8)self.init_step=16#初始步骤16eliflevel==3:self.__init__(7,7)self.init_step=18#初始步骤18eliflevel==4:self.__init__(9,7)row,col=self.row,self.colself.animal[row][col]=self.animal[row][col+7]=self.animal[row][col+8]=self.animal[row+1][col+8]=\self.animal[row+5][col]=self.animal[row+6][col]=self.animal[row+6][col+1]=\self.animal[row+6][col+8]=-1self.init_step=20eliflevel==5:self.__init__(8,9)row,col=self.row,self.colself.animal[row][col+7]=self.animal[row+2][col]=self.animal[row+5][col]=\self.animal[row+3][col+7]=\self.animal[row+6][col+7]=self.animal[row+8][col]=-1self.init_step=20eliflevel==6:self.__init__(9,9)row,col=self.row,self.colself.animal[row][col]=self.animal[row][col+8]=self.animal[row+2][col+4]=\self.animal[row+3][col+2]=\self.animal[row+3][col+6]=self.animal[row+8][col]=self.animal[row+8][col+8]=-1foriinrange(row+4,row+6):forjinrange(col+3,col+6):self.animal[i][j]=-1self.init_step=28eliflevel==7:self.__init__(9,9)row,col=self.row,self.colforiinrange(row,row+9):self.animal[i][col+4]=-1forjinrange(col,col+4):self.animal[row+3][j]=-1forjinrange(col+5,col+9):self.animal[row+5][j]=-1self.init_step=25eliflevel==8:self.__init__(7,8)row,col=self.row,self.colforiinrange(row+2,row+5):forjinrange(col+1,col+6):self.ice_list[i][j]=1self.init_step=21eliflevel==9:self.__init__(9,9)row,col=self.row,self.colself.animal[row][col+4]=self.animal[row+4][col]=self.animal[row+4][col+8]=\self.animal[row+8][col+4]=-1foriinrange(row+1,row+8):forjinrange(col+1,col+8):self.ice_list[i][j]=1self.init_step=35else:self.__init__(9,9)row,col=self.row,self.colforiinrange(row,row+2):forjinrange(col,col+9):self.animal[i][j]=-1self.animal[row][col+4]=randint(0,5)self.animal[row+1][col+2]=randint(0,5)self.animal[row+1][col+4]=randint(0,5)self.animal[row+1][col+6]=randint(0,5)self.animal[row+2][col+1]=self.animal[row+3][col+1]=self.animal[row+2][col+3]=\self.animal[row+3][col+3]=\self.animal[row+2][col+5]=self.animal[row+3][col+5]=self.animal[row+2][col+7]=\self.animal[row+3][col+7]=self.animal[row+8][col]=self.animal[row+8][col+8]=-1foriinrange(row+4,row+8):forjinrange(col,col+9):self.ice_list[i][j]=1self.ice_list[row+2][col+4]=self.ice_list[row+3][col+2]=self.ice_list[row+3][col+4]=\self.ice_list[row+3][col+6]=1self.init_step=40self.type=0self.energy_num-=5self.success_board=Board(Board.success,[200,0])#成功的面板self.fail_board=Board(Board.fail,[200,0])#失败的面板self.step=self.init_stepself.score=0self.animal_num=[0,0,0,0,0,0]self.ice_num=0self.reset_mode=Falsedefnum_add(self):"""增加得分"""ifself.num_sign:self.money+=self.score*2ifself.score=10:#L1:10只青蛙self.type=1#通过第一关self.num_add()elifself.level==2:ifself.animal_num[1]>=21:#L2:21只熊self.type=1#通过第二关self.num_add()elifself.level==3:ifself.animal_num[4]>=16andself.animal_num[5]>=16:#L3:16只青蛙和16头牛self.type=1#通过第三关self.num_add()elifself.level==4:ifself.animal_num[5]>=18andself.animal_num[2]>=18:#L4:18头牛和18只小鸡self.type=1#通过第四关self.num_add()elifself.level==5:ifself.animal_num[2]>=28andself.animal_num[0]>=28:#L5:28只小鸡和28只狐狸self.type=1#通过第五关self.num_add()elifself.level==6:ifself.animal_num[4]>=70:#L6:70只青蛙self.type=1#通过第六关self.num_add()elifself.level==7:ifself.animal_num[2]>=36andself.animal_num[1]>=36\andself.animal_num[0]>=36:#L7:36只小鸡、36只熊和36只狐狸self.type=1#通过第七关self.num_add()elifself.level==8:ifself.ice_num>=15:#L8:15冰块self.type=1#通过第八关self.num_add()elifself.level==9:ifself.ice_num>=49:#L9:49冰块self.type=1#通过第九关self.num_add()else:ifself.ice_num>=39:#L10:39冰块self.type=1#通过第十关self.num_add()self.judge_next(self.type,self.score)123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875level_tree.pyimportpygamefrompygameimportDOUBLEBUFfrompygame.timeimportdelayfromdissipate.soundsimportplay_sound,Sounds#导入声音播放功能和声音资源fromdissipate.spritesimportTree#导入关卡树的类classLevelTreeManager:"""关卡树管理器类,用于管理关卡树及其相关功能。"""__screen_size=(900,600)#屏幕尺寸screen=pygame.display.set_mode(__screen_size,DOUBLEBUF,32)#设置屏幕显示模式fruit_list=[]#用于存储水果对象的列表fruit_image=pygame.image.load(Tree.fruit).convert_alpha()#加载水果图片fruit_width=fruit_image.get_width()#获取水果图片宽度fruit_height=fruit_image.get_height()#获取水果图片高度type=0#场景类型,0表示关卡树场景,1表示能量场景energy_full=False#能量已满标志money_empty=False#金钱不足标志defdisplay_text(self,text,position,txt_size=25,txt_color=(255,255,255)):"""显示指定的文本内容。参数:text:要显示的文本position:文本位置txt_size:文本大小txt_color:文本颜色"""my_font=pygame.font.SysFont(None,txt_size)#创建字体对象text_screen=my_font.render(text,True,txt_color)#渲染文本self.screen.blit(text_screen,position)#在屏幕上绘制文本defdraw_tree(self,energy_num,money_num):"""绘制游戏中的关卡树和相关资源。参数:energy_num:当前能量值money_num:当前金钱数量"""Tree(Tree.tree,(0,600)).draw(self.screen)#绘制关卡树Tree(Tree.energy_num,Tree.energy_num_position).draw(self.screen)#绘制能量数ifenergy_num>30:self.display_text(str(30)+'/30',(22,55),21)#显示最大能量值else:self.display_text(str(energy_num)+'/30',(22,55),21)#显示当前能量值Tree(Tree.money,(15,135)).draw(self.screen)#绘制金钱self.display_text(str(money_num),(32,124),21)#显示当前金钱数量foriinrange(0,10):#绘制水果Tree(Tree.fruit,Tree.position[i]).draw(self.screen)self.display_text(str(i+1),(Tree.position[i][0]+15,Tree.position[i][1]-47))ifself.type==1:Tree(Tree.energy_buy,Tree.energy_buy_position).draw(self.screen)#绘制购买能量按钮ifself.energy_full:self.display_text('energyisfull!',(430,310),30,(255,0,0))#显示能量已满提示pygame.display.flip()#更新屏幕显示delay(500)#延迟500毫秒self.energy_full=False#重置能量已满标志ifself.money_empty:self.display_text('moneyisnotenough!',(410,310),30,(255,0,0))#显示金钱不足提示pygame.display.flip()#更新屏幕显示delay(500)#延迟500毫秒self.money_empty=False#重置金钱不足标志defmouse_select(self,mgr,mouse_x,mouse_y,level,energy_num,money_num):"""处理鼠标事件。参数:mgr:管理器对象mouse_x:鼠标x坐标mouse_y:鼠标y坐标level:当前等级energy_num:当前能量值money_num:当前金钱数量"""ifself.type==0:#关卡树场景foriinrange(0,10):ifTree.position[i][0]=30:self.energy_full=True#能量已满标志设为真elifenergy_num=50:energy_num+=5#增加能量money_num-=50#减少金钱elif619=543:#到达底部边界self.speed=[0,-45]ifself.speed==[0,-45]andself.rect.bottom
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 会员注册

本版积分规则

QQ|手机版|心飞设计-版权所有:微度网络信息技术服务中心 ( 鲁ICP备17032091号-12 )|网站地图

GMT+8, 2025-1-11 06:07 , Processed in 0.600199 second(s), 26 queries .

Powered by Discuz! X3.5

© 2001-2025 Discuz! Team.

快速回复 返回顶部 返回列表