向导

推荐:pubg加速器

植物大战僵尸重叠种植-Python植物大战僵尸代码实现

快使用OurPlay来免费加速植物大战僵尸!点击下载:【下载OurPlay免费加速】

webbanner3.png

完整代码

植物卡片类

卡片栏类

鼠标图片切换

提示种在哪个方格中

编译环境

功能介绍

最近一直在给这个植物大战僵尸游戏添加新的植物和僵尸,因为网上的图片资源有限,能加的植物和僵尸比较少,目前进展如下。

功能实现如下:

支持的植物类型:太阳花,豌豆射手,寒冰射手,坚果,樱桃炸弹。新增加植物:双重豌豆射手,三重豌豆射手,食人花,小喷菇,土豆地雷,倭瓜。

支持的僵尸类型:普通僵尸,棋子僵尸,路障僵尸,铁桶僵尸。新增加读报僵尸。

使用json文件保存关卡信息,设置僵尸出现的时间和位置。

增加每关开始时选择上场植物。

增加除草机。

Python植物大战僵尸代码实现(1):图片加载和显示切换

https://blog.csdn.net/marble_xu/article/details/100129768

下面是游戏的截图:

图1:新增的植物和僵尸

图2:每关开始选择上场植物卡片

图3:选择植物在哪里种植

如图3所示,游戏中可以种植物的方格一共有45个(有5行,每行9列)。

这篇文章要介绍的是:

上方植物卡片栏的实现。

点击植物卡片,鼠标切换为植物图片。

鼠标移动时,判断当前在哪个方格中,并显示半透明的植物作为提示。

游戏实现代码的github链接植物大战僵尸

https://github.com/marblexu/PythonPlantsVsZombies

这边是csdn的下载链接植物大战僵尸

https://download.csdn.net/download/marble_xu/11982275

代码实现

所有的植物卡片的名称和属性都保存在单独的list中,每个listindex都对应一种植物。

比如listindex0就是太阳花:

card_name_list[0]是太阳花卡片的名字,用来获取太阳花卡片的图片。

plant_name_list[0]是太阳花的名字,用来获取太阳花卡片的图片。

plant_sun_list[0]是种植太阳花需要花费的太阳点数。

plant_frozen_time_list[0]是太阳花的冷却时间。

代码在source\component\menubar.py中

card_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_PUFFMUSHROOM,c.CARD_POTATOMINE,c.CARD_SQUASH]plant_name_list=[c.SUNFLOWER,c.PEASHOOTER,c.SNOWPEASHOOTER,c.WALLNUT,c.CHERRYBOMB,c.THREEPEASHOOTER,c.REPEATERPEA,c.CHOMPER,c.PUFFMUSHROOM,c.POTATOMINE,c.SQUASH]plant_sun_list=[50,100,175,50,150,325,200,150,0,25,50]plant_frozen_time_list=[0,5000,5000,10000,5000,5000,5000,5000,8000,8000,8000]all_card_list=[0,1,2,3,4,5,6,7,8,9,10]

代码在source\component\menubar.py中,每个植物卡片是一个单独的Card类,用来显示这个植物。

checkMouseClick函数:判断鼠标是否点击到这个卡片

canClick:判断这个卡片是否能种植(有没有足够的点数,是否还在冷却时间内)

update函数:通过设置图片的透明度来表示这个卡片是否能选择

classCard():def__init__(self,x,y,name_index,scale=0.78):self.loadFrame(card_name_list[name_index],scale)self.rect=self.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.select=True

defloadFrame(self,name,scale):frame=tool.GFX[name]rect=frame.get_rect()width,height=rect.w,rect.h

self.image=tool.get_image(frame,0,0,width,height,c.BLACK,scale)defcheckMouseClick(self,mouse_pos):x,y=mouse_posif(x>=self.rect.xandxy>=self.rect.yandyreturnTruereturnFalse

defcanClick(self,sun_value,current_time):ifself.sun_costself.frozen_time:returnTruereturnFalse

defcanSelect(self):returnself.select

defsetSelect(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_time

defupdate(self,sun_value,current_time):if(self.sun_cost>sun_valueor(current_time-self.frozen_timer)self.image.set_alpha(128)else:self.image.set_alpha(255)

defdraw(self,surface):surface.blit(self.image,self.rect)

代码在source\component\menubar.py中,MenuBar类显示图3中的植物卡片栏:

self.sun_value:当前采集的太阳点数

self.card_list:植物卡片的list

setupCards函数:遍历初始化__init__函数中传入这个关卡选好的植物卡片list,依次创建Card类,设置每个卡片的显示位置。

checkCardClick函数:检查鼠标是否点击了卡片栏上的某个植物卡片,如果选择了一个可种植的卡片,返回结果。

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.sun_cost)breakreturnresultdefcheckMenuBarClick(self,mouse_pos):x,y=mouse_posif(x>=self.rect.xandxy>=self.rect.yandyreturnTruereturnFalse

defdecreaseSunValue(self,value):self.sun_value-=value

defincreaseSunValue(self,value):self.sun_value+=value

defsetCardFrozenTime(self,plant_name):forcardinself.card_list:ifplant_name_list[card.name_index]==plant_name:card.setFrozenTime(self.current_time)break

defdrawSunValue(self):self.value_image=getSunValueImage(self.sun_value)self.value_rect=self.value_image.get_rect()self.value_rect.x=21self.value_rect.y=self.rect.bottom-21self.image.blit(self.value_image,self.value_rect)

defdraw(self,surface):self.drawSunValue()surface.blit(self.image,self.rect)forcardinself.card_list:card.draw(surface)

代码在source\state\level.py中,setupMouseImage函数实现鼠标图片切换为选中的植物。

self.mouse_image:根据plant_name获取选中的植物图片

self.mouse_rect:选中植物图片的位置,在drawMouseShow函数中,需要将植物图片的位置设置成当前鼠标的位置

pg.mouse.set_visible(False):隐藏默认的鼠标显示,这样效果就是鼠标图片切换为选中的植物了。

defsetupMouseImage(self,plant_name,plant_cost):frame_list=tool.GFX[plant_name]ifplant_nameintool.PLANT_RECT:data=tool.PLANT_RECT[plant_name]x,y,width,height=data['x'],data['y'],data['width'],data['height']else:x,y=0,0rect=frame_list[0].get_rect()width,height=rect.w,rect.h

ifplant_name==c.POTATOMINEorplant_name==c.SQUASH:color=c.WHITEelse:color=c.BLACKself.mouse_image=tool.get_image(frame_list[0],x,y,width,height,color,1)self.mouse_rect=self.mouse_image.get_rect()pg.mouse.set_visible(False)self.drag_plant=Trueself.plant_name=plant_nameself.plant_cost=plant_cost

defdrawMouseShow(self,surface):ifself.hint_plant:surface.blit(self.hint_image,self.hint_rect)x,y=pg.mouse.get_pos()self.mouse_rect.centerx=xself.mouse_rect.centery=ysurface.blit(self.mouse_image,self.mouse_rect)

先看下map类,代码在source\component\map.py中

self.map:二维list,用来保存每个方格的状态。每个entry初始化为0,表示可以种植物,值为1时表示这个方格已经种了植物。

getMapIndex函数:传入参数是游戏中的坐标位置(比如当前鼠标的位置),返回该位置在地图的哪个方格中。

getMapGridPos函数:传入一个方格的index,返回在该方格中种植物的坐标位置。

showPlant函数:根据传入的坐标位置,判断该位置所在的方格是否能种植物,如果能种,就返回返回在该方格中种植物的坐标位置。

MAP_EMPTY=0MAP_EXIST=1

classMap():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<0ormap_x>=self.widthormap_y<0ormap_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]=type

defgetRandomMapIndex(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)returnpos

代码在source\state\level.py中:

canSeedPlant函数:判断当前鼠标位置能否种植物

setupHintImage函数:如果当前鼠标位置能种植物,且有选择了一个植物卡片,则设置self.hint_image显示当前会在哪一个方格中种植物,self.hint_rect是植物种的坐标位置。

defcanSeedPlant(self):x,y=pg.mouse.get_pos()returnself.map.showPlant(x,y)defsetupHintImage(self):pos=self.canSeedPlant()ifposandself.mouse_image:if(self.hint_imageandpos[0]==self.hint_rect.xandpos[1]==self.hint_rect.y):returnwidth,height=self.mouse_rect.w,self.mouse_rect.himage=pg.Surface([width,height])image.blit(self.mouse_image,(0,0),(0,0,width,height))image.set_colorkey(c.BLACK)image.set_alpha(128)self.hint_image=imageself.hint_rect=image.get_rect()self.hint_rect.centerx=pos[0]self.hint_rect.bottom=pos[1]self.hint_plant=Trueelse:self.hint_plant=False

python3.7+pygame1.9

你点的每个“在看”,我都认真当成了AI

以上就是植物大战僵尸重叠种植-Python植物大战僵尸代码实现相关内容,希望对玩家有所帮助,更多植物大战僵尸相关攻略资讯,尽在ourplay攻略资讯频道。

植物大战僵尸
植物大战僵尸
专区