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

Python版植物大战僵尸+源码

[复制链接]

2万

主题

0

回帖

7万

积分

超级版主

积分
72012
发表于 2024-9-9 09:27:01 | 显示全部楼层 |阅读模式
文章目录粉丝专属:写在前面:功能实现环境要求怎么玩个性化定义项目演示:源码分享Map地图:Menubar.py主菜单主函数:项目开源地址粉丝专属:写在前面:今天给大家推荐一个Gtihub开源项目:PythonPlantsVsZombies,翻译成中就是植物大战僵尸。《植物大战僵尸》是一款极富策略性的小游戏。可怕的僵尸即将入侵,每种僵尸都有不同的特点,例如铁桶僵尸拥有极强的抗击打能力,矿工僵尸可以挖地道绕过种植在土壤表面的植物等。玩家防御僵尸的方式就是栽种植物。49种植物每种都有不同的功能,例如樱桃炸弹可以和周围一定范围内的所有僵尸同归于尽,而食人花可以吃掉最靠近自己的一只僵尸。玩家可以针对不同僵尸的弱点来合理地种植植物,这也是胜利的诀窍。游戏根据玩法不同分为五种游戏模式:冒险模式、迷你模式、解谜模式、生存模式、禅境花园。加之黑夜、屋顶、浓雾以及泳池之类的障碍增加了其挑战性。该游戏近乎永无止境。功能实现支持的植物:向日葵、豌豆射手、胡桃、雪豌豆射手、樱桃炸弹、三豌豆射手、大嘴花、puffshroom、马铃薯胺、穗状杂草、南瓜、胆小菇、墨西哥胡椒、阳光菇、冰川菇、催眠蘑菇。支持僵尸:普通僵尸,旗帜僵尸,路障僵尸,铁桶僵尸,报纸僵尸。支持在关卡开始时选择植物卡片。支持白天级别、夜间级别、移动卡选择级别和胡桃保龄球级别。环境要求1、python3.7注意:Python3.7是最佳运行环境,但是不是强制性要求。对于Linux:如果你的Linux有预装的Python3+就可以运行了。LINUXMint操作系统直接升级到Python3.7有可能导致系统自带的python版本无法执行。2、Python-Pygame1.9怎么玩使用鼠标收集阳光,选择植物卡片并播种植物您可以通过更改source/constants.py中的START_LEVEL_NUM值来设置起始级别级别1和2:天级别第3级:夜间级别第4级:移动卡片选择级别5级:墙果保龄球级别个性化定义游戏的关卡数据,存储在json文件里的。具体目录:PythonPlantsVsZombies-master\source\data。我们可以进行自定义配置,例如僵尸的位置和时间,背景信息。项目演示:源码分享Map地图:__author__='marble_xu'importrandomimportpygameaspgfrom..importtoolfrom..importconstantsascclassMap():def__init__(self,width,height):self.width=widthself.height=heightself.map=[[0forxinrange(self.width)]foryinrange(self.height)]defisValid(self,map_x,map_y):if(map_x=self.widthormap_y=self.height):returnFalsereturnTruedefisMovable(self,map_x,map_y):return(self.map[map_y][map_x]==c.MAP_EMPTY)defgetMapIndex(self,x,y):x-=c.MAP_OFFSET_Xy-=c.MAP_OFFSET_Yreturn(x//c.GRID_X_SIZE,y//c.GRID_Y_SIZE)defgetMapGridPos(self,map_x,map_y):return(map_x*c.GRID_X_SIZE+c.GRID_X_SIZE//2+c.MAP_OFFSET_X,map_y*c.GRID_Y_SIZE+c.GRID_Y_SIZE//5*3+c.MAP_OFFSET_Y)defsetMapGridType(self,map_x,map_y,type):self.map[map_y][map_x]=typedefgetRandomMapIndex(self):map_x=random.randint(0,self.width-1)map_y=random.randint(0,self.height-1)return(map_x,map_y)defshowPlant(self,x,y):pos=Nonemap_x,map_y=self.getMapIndex(x,y)ifself.isValid(map_x,map_y)andself.isMovable(map_x,map_y):pos=self.getMapGridPos(map_x,map_y)returnpos123456789101112131415161718192021222324252627282930313233343536373839404142434445Menubar.py__author__='marble_xu'importrandomimportpygameaspgfrom..importtoolfrom..importconstantsascPANEL_Y_START=87PANEL_X_START=22PANEL_Y_INTERNAL=74PANEL_X_INTERNAL=53CARD_LIST_NUM=8card_name_list=[c.CARD_SUNFLOWER,c.CARD_PEASHOOTER,c.CARD_SNOWPEASHOOTER,c.CARD_WALLNUT,c.CARD_CHERRYBOMB,c.CARD_THREEPEASHOOTER,c.CARD_REPEATERPEA,c.CARD_CHOMPER,c.CARD_PUFFSHROOM,c.CARD_POTATOMINE,c.CARD_SQUASH,c.CARD_SPIKEWEED,c.CARD_JALAPENO,c.CARD_SCAREDYSHROOM,c.CARD_SUNSHROOM,c.CARD_ICESHROOM,c.CARD_HYPNOSHROOM,c.CARD_WALLNUT,c.CARD_REDWALLNUT]plant_name_list=[c.SUNFLOWER,c.PEASHOOTER,c.SNOWPEASHOOTER,c.WALLNUT,c.CHERRYBOMB,c.THREEPEASHOOTER,c.REPEATERPEA,c.CHOMPER,c.PUFFSHROOM,c.POTATOMINE,c.SQUASH,c.SPIKEWEED,c.JALAPENO,c.SCAREDYSHROOM,c.SUNSHROOM,c.ICESHROOM,c.HYPNOSHROOM,c.WALLNUTBOWLING,c.REDWALLNUTBOWLING]plant_sun_list=[50,100,175,50,150,325,200,150,0,25,50,100,125,25,25,75,75,0,0]plant_frozen_time_list=[7500,7500,7500,30000,50000,7500,7500,7500,7500,30000,30000,7500,50000,7500,7500,50000,30000,0,0]all_card_list=[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16]defgetSunValueImage(sun_value):font=pg.font.SysFont(None,22)width=32msg_image=font.render(str(sun_value),True,c.NAVYBLUE,c.LIGHTYELLOW)msg_rect=msg_image.get_rect()msg_w=msg_rect.widthimage=pg.Surface([width,17])x=width-msg_wimage.fill(c.LIGHTYELLOW)image.blit(msg_image,(x,0),(0,0,msg_rect.w,msg_rect.h))image.set_colorkey(c.BLACK)returnimagedefgetCardPool(data):card_pool=[]forcardindata:tmp=card['name']fori,nameinenumerate(plant_name_list):ifname==tmp:card_pool.append(i)breakreturncard_poolclassCard():def__init__(self,x,y,name_index,scale=0.78):self.loadFrame(card_name_list[name_index],scale)self.rect=self.orig_image.get_rect()self.rect.x=xself.rect.y=yself.name_index=name_indexself.sun_cost=plant_sun_list[name_index]self.frozen_time=plant_frozen_time_list[name_index]self.frozen_timer=-self.frozen_timeself.refresh_timer=0self.select=TruedefloadFrame(self,name,scale):frame=tool.GFX[name]rect=frame.get_rect()width,height=rect.w,rect.hself.orig_image=tool.get_image(frame,0,0,width,height,c.BLACK,scale)self.image=self.orig_imagedefcheckMouseClick(self,mouse_pos):x,y=mouse_posif(x>=self.rect.xandx=self.rect.yandyself.frozen_time:returnTruereturnFalsedefcanSelect(self):returnself.selectdefsetSelect(self,can_select):self.select=can_selectifcan_select:self.image.set_alpha(255)else:self.image.set_alpha(128)defsetFrozenTime(self,current_time):self.frozen_timer=current_timedefcreateShowImage(self,sun_value,current_time):'''createacardimagetoshowcooldownstatusordisablestatuswhenhavenotenoughsunvalue'''time=current_time-self.frozen_timeriftimesun_value:#disablestatusimage=self.orig_image.copy()image.set_alpha(192)else:image=self.orig_imagereturnimagedefupdate(self,sun_value,current_time):if(current_time-self.refresh_timer)>=250:self.image=self.createShowImage(sun_value,current_time)self.refresh_timer=current_timedefdraw(self,surface):surface.blit(self.image,self.rect)classMenuBar():def__init__(self,card_list,sun_value):self.loadFrame(c.MENUBAR_BACKGROUND)self.rect=self.image.get_rect()self.rect.x=10self.rect.y=0self.sun_value=sun_valueself.card_offset_x=32self.setupCards(card_list)defloadFrame(self,name):frame=tool.GFX[name]rect=frame.get_rect()frame_rect=(rect.x,rect.y,rect.w,rect.h)self.image=tool.get_image(tool.GFX[name],*frame_rect,c.WHITE,1)defupdate(self,current_time):self.current_time=current_timeforcardinself.card_list:card.update(self.sun_value,self.current_time)defcreateImage(self,x,y,num):ifnum==1:returnimg=self.imagerect=self.image.get_rect()width=rect.wheight=rect.hself.image=pg.Surface((width*num,height)).convert()self.rect=self.image.get_rect()self.rect.x=xself.rect.y=yforiinrange(num):x=i*widthself.image.blit(img,(x,0))self.image.set_colorkey(c.BLACK)defsetupCards(self,card_list):self.card_list=[]x=self.card_offset_xy=8forindexincard_list:x+=55self.card_list.append(Card(x,y,index))defcheckCardClick(self,mouse_pos):result=Noneforcardinself.card_list:ifcard.checkMouseClick(mouse_pos):ifcard.canClick(self.sun_value,self.current_time):result=(plant_name_list[card.name_index],card)breakreturnresultdefcheckMenuBarClick(self,mouse_pos):x,y=mouse_posif(x>=self.rect.xandx=self.rect.yandy=self.button_rect.xandx=self.button_rect.yandy=self.rect.xandx=self.rect.yandy=c.CARD_MOVE_TIME:ifself.rect.x>left_x:self.rect.x-=1self.image=self.createShowImage()self.move_timer+=c.CARD_MOVE_TIMEdefdraw(self,surface):surface.blit(self.image,self.rect)classMoveBar():def__init__(self,card_pool):self.loadFrame(c.MOVEBAR_BACKGROUND)self.rect=self.image.get_rect()self.rect.x=90self.rect.y=0self.card_start_x=self.rect.x+8self.card_end_x=self.rect.right-5self.card_pool=card_poolself.card_list=[]self.create_timer=-c.MOVEBAR_CARD_FRESH_TIMEdefloadFrame(self,name):frame=tool.GFX[name]rect=frame.get_rect()frame_rect=(rect.x,rect.y,rect.w,rect.h)self.image=tool.get_image(tool.GFX[name],*frame_rect,c.WHITE,1)defcreateCard(self):iflen(self.card_list)>0andself.card_list[-1].rect.right>self.card_end_x:returnFalsex=self.card_end_xy=6index=random.randint(0,len(self.card_pool)-1)card_index=self.card_pool[index]card_name=card_name_list[card_index]+'_move'plant_name=plant_name_list[card_index]self.card_list.append(MoveCard(x,y,card_name,plant_name))returnTruedefupdate(self,current_time):self.current_time=current_timeleft_x=self.card_start_xforcardinself.card_list:card.update(left_x,self.current_time)left_x=card.rect.right+1if(self.current_time-self.create_timer)>c.MOVEBAR_CARD_FRESH_TIME:ifself.createCard():self.create_timer=self.current_timedefcheckCardClick(self,mouse_pos):result=Noneforindex,cardinenumerate(self.card_list):ifcard.checkMouseClick(mouse_pos):result=(card.plant_name,card)breakreturnresultdefcheckMenuBarClick(self,mouse_pos):x,y=mouse_posif(x>=self.rect.xandx=self.rect.yandy=self.option_rect.xandx=self.option_rect.yandy200:self.option_frame_index+=1ifself.option_frame_index>=2:self.option_frame_index=0self.option_timer=self.current_timeself.option_image=self.option_frames[self.option_frame_index]if(self.current_time-self.option_start)>1300:self.done=Truesurface.blit(self.bg_image,self.bg_rect)surface.blit(self.option_image,self.option_rect)123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869主函数:__author__='marble_xu'from.importtoolfrom.importconstantsascfrom.stateimportmainmenu,screen,leveldefmain():game=tool.Control()state_dict={c.MAIN_MENU:mainmenu.Menu(),c.GAME_VICTORY:screen.GameVictoryScreen(),c.GAME_LOSE:screen.GameLoseScreen(),c.LEVEL:level.Level()}game.setup_states(state_dict,c.MAIN_MENU)game.main()1234567891011121314项目开源地址https://github.com/marblexu/PythonPlantsVsZombies
回复

使用道具 举报

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

本版积分规则

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

GMT+8, 2025-1-10 22:41 , Processed in 0.477948 second(s), 26 queries .

Powered by Discuz! X3.5

© 2001-2025 Discuz! Team.

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