python植物大战僵尸脚本_用Python实现植物大战僵尸游戏,很酷

以前很火的植物大战僵尸游戏, 本想在网上找个python版本游戏学习下,无奈没有发现比较完整的,那就自己来写一个把。图片资源是从github上下载的,因为图片资源有限,只能实现几种植物和僵尸。

功能实现如下:

支持的植物类型:太阳花,豌豆射手,寒冰射手,坚果,樱桃炸弹。新增加植物:双重豌豆射手,三重豌豆射手。

支持的僵尸类型:普通僵尸,棋子僵尸,路障僵尸,铁桶僵尸。

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

新增加除草机。

下面是游戏的截图:

另外大家要注意:不管你是为了Python就业还是兴趣爱好,记住:项目开发经验永远是核心,如果你没有2020最新python入门到高级实战视频教程,可以去小编的Python交流.裙 :七衣衣九七七巴而五(数字的谐音)转换下可以找到了,里面很多新python教程项目,还可以跟老司机交流讨教!

1

图2

1

1

图片显示切换

从图1和图2可以看到,僵尸的行走和攻击时的图片显示会有不同,这篇文章讲下如何进行图片显示的切换。

以上面的路障僵尸为例,一共有下面几种图片类型。

带着路障行走

带着路障攻击

不带路障行走(即变成普通僵尸的行走)

不带路障攻击(即变成普通僵尸的攻击)

没有头的行走

没有头的攻击

死亡

图3是路障僵尸的这7种图片类型的示例

1

图片加载

植物大战僵尸的图片资源比较特别,一种图片类型的每一个动作是一个单独的图片,如图4是路障僵尸带着路障攻击的动作图片,一共有11个图片,所以加载图片的代码要做对应的修改。

1

完整代码

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

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

图片加载

在 source\tool.py 中 load_all_gfx 函数遍历resources\graphics 目录和子目录。

代码中做了一个简单的区分:

如果在resources\graphics\subfolder\ 目录中是图片,那就是单独的一个图片,比如resources\graphics\Screen 目录中的界面图片

如果在resources\graphics\subfolder\ 目录中是子目录,那这个子目录或子子目录中的所有图片都属于一个图片类型,比如resources\graphics\Zombies\ConeheadZombie\ConeheadZombieAttack 目录下就是路障僵尸带着路障攻击的动作图片, 如图4所示。

1 def load_all_gfx(directory, colorkey=c.WHITE, accept=('.png', '.jpg', '.bmp', '.gif')):

2 graphics = {}

3 for name1 in os.listdir(directory):

4 # subfolders under the folder resources\graphics

5 dir1 = os.path.join(directory, name1)

6 if os.path.isdir(dir1):

7 for name2 in os.listdir(dir1):

8 dir2 = os.path.join(dir1, name2)

9 if os.path.isdir(dir2):

10 # e.g. subfolders under the folder resources\graphics\Zombies

11 for name3 in os.listdir(dir2):

12 dir3 = os.path.join(dir2, name3)

13 # e.g. subfolders or pics under the folder resources\graphics\Zombies\ConeheadZombie

14 if os.path.isdir(dir3):

15 # e.g. it's the folder resources\graphics\Zombies\ConeheadZombie\ConeheadZombieAttack

16 image_name, _ = os.path.splitext(name3)

17 graphics[image_name] = load_image_frames(dir3, image_name, colorkey, accept)

18 else:

19 # e.g. pics under the folder resources\graphics\Plants\Peashooter

20 image_name, _ = os.path.splitext(name2)

21 graphics[image_name] = load_image_frames(dir2, image_name, colorkey, accept)

22 break

23 else:

24 # e.g. pics under the folder resources\graphics\Screen

25 name, ext = os.path.splitext(name2)

26 if ext.lower() in accept:

27 img = pg.image.load(dir2)

28 if img.get_alpha():

29 img = img.convert_alpha()

30 else:

31 img = img.convert()

32 img.set_colorkey(colorkey)

33 graphics[name] = img

34 return graphics

35

36 GFX = load_all_gfx(os.path.join("resources","graphics"))复制代码

load_image_frames 函数 将目录中的所有图片按照图片名称中的index值为key,保存在tmp 字典中。比如图片名称为"ConeheadZombieAttack_2",它的index值就为2。

然后将图片按index值依次加入到 frame_list 中。

1 def load_image_frames(directory, image_name, colorkey, accept):

2 frame_list = []

3 tmp = {}

4 # image_name is "Peashooter", pic name is 'Peashooter_1', get the index 1

5 index_start = len(image_name) + 1

6 frame_num = 0;

7 for pic in os.listdir(directory):

8 name, ext = os.path.splitext(pic)

9 if ext.lower() in accept:

10 index = int(name[index_start:])

11 img = pg.image.load(os.path.join(directory, pic))

12 if img.get_alpha():

13 img = img.convert_alpha()

14 else:

15 img = img.convert()

16 img.set_colorkey(colorkey)

17 tmp[index]= img

18 frame_num += 1

19

20 for i in range(frame_num):

21 frame_list.append(tmp[i])

22 return frame_list复制代码

图片显示切换

在 source\component\zombie.py 中, Zombie 类是所有僵尸类的父类,初始化 函数调用loadImages函数加载所有支持的图片类型,设置Sprite 精灵类显示需要的成员变量 image和rect。

loadFrames函数给具体的子类来调用,获取图片。

1 class Zombie(pg.sprite.Sprite):

2 def __init__(self, x, y, name, health, head_group=None, damage=1):

3 pg.sprite.Sprite.__init__(self)

4

5 self.name = name

6 self.frames = []

7 self.frame_index = 0

8 self.loadImages()

9 self.frame_num = len(self.frames)

10

11 self.image = self.frames[self.frame_index]

12 self.rect = self.image.get_rect()

13 self.rect.centerx = x

14 self.rect.bottom = y

15 ...

16

17 def loadFrames(self, frames, name, image_x):

18 frame_list = tool.GFX[name]

19 rect = frame_list[0].get_rect()

20 width, height = rect.w, rect.h

21 width -= image_x

22

23 for frame in frame_list:

24 frames.append(tool.get_image(frame, image_x, 0, width, height))复制代码

基本的功能都在Zombie 父类中实现,如果子类有特殊需求,可以重定义同名函数。

update 函数:每个tick 都会调用的入口函数,用来更新僵尸的位置,切换状态和更新图片显示。

handleState 函数:根据僵尸当前的状态来执行不同的函数。

animation 函数:每隔指定的 animate_interval 时间会显示图片类型的下一个动作。

1 def update(self, game_info):

2 self.current_time = game_info[c.CURRENT_TIME]

3 self.handleState()

4 self.animation()

5

6 def handleState(self):

7 if self.state == c.WALK:

8 self.walking()

9 elif self.state == c.ATTACK:

10 self.attacking()

11 elif self.state == c.DIE:

12 self.dying()

13

14 def animation(self):

15 if (self.current_time - self.animate_timer) > self.animate_interval:

16 self.frame_index += 1

17 if self.frame_index >= self.frame_num:

18 if self.state == c.DIE:

19 self.kill()

20 return

21 self.frame_index = 0

22 self.animate_timer = self.current_time

23

24 self.image = self.frames[self.frame_index]复制代码

下面四个函数是修改僵尸的当前状态和图片显示。

setWalk 函数:修改为行走状态,图片显示会根据不同值设置不同的图片类型。

setAttack 函数:修改为攻击状态,图片显示会根据不同值设置不同的图片类型。

setDie 函数:修改为死亡状态。

changeFrames 函数:修改图片类型后,需要重新设置成员变量frame_num,frame_index, image和rect的值。

1 def setWalk(self):

2 self.state = c.WALK

3 self.animate_interval = 150

4

5 if self.helmet:

6 self.changeFrames(self.helmet_walk_frames)

7 elif self.losHead:

8 self.changeFrames(self.losthead_walk_frames)

9 else:

10 self.changeFrames(self.walk_frames)

11

12 def setAttack(self, plant):

13 self.plant = plant

14 self.state = c.ATTACK

15 self.animate_interval = 100

16

17 if self.helmet:

18 self.changeFrames(self.helmet_attack_frames)

19 elif self.losHead:

20 self.changeFrames(self.losthead_attack_frames)

21 else:

22 self.changeFrames(self.attack_frames)

23

24 def setDie(self):

25 self.state = c.DIE

26 self.animate_interval = 200

27 self.changeFrames(self.die_frames)

28

29 def changeFrames(self, frames):

30 '''change image frames and modify rect position'''

31 self.frames = frames

32 self.frame_num = len(self.frames)

33 self.frame_index = 0

34

35 bottom = self.rect.bottom

36 centerx = self.rect.centerx

37 self.image = self.frames[self.frame_index]

38 self.rect = self.image.get_rect()

39 self.rect.bottom = bottom

40 self.rect.centerx = centerx复制代码

路障僵尸类就比较简单,只需要实现 loadImages 函数,调用loadFrames函数加载该种僵尸支持的图片类型,这边主要的差异在于不同种类僵尸的图片类型的名称会有区别。

1 class ConeHeadZombie(Zombie):

2 def __init__(self, x, y, head_group):

3 Zombie.__init__(self, x, y, c.CONEHEAD_ZOMBIE, c.CONEHEAD_HEALTH, head_group)

4 self.helmet = True

5

6 def loadImages(self):

7 self.helmet_walk_frames = []

8 self.helmet_attack_frames = []

9 self.walk_frames = []

10 self.attack_frames = []

11 self.losthead_walk_frames = []

12 self.losthead_attack_frames = []

13 self.die_frames = []

14

15 helmet_walk_name = self.name

16 helmet_attack_name = self.name + 'Attack'

17 walk_name = c.NORMAL_ZOMBIE

18 attack_name = c.NORMAL_ZOMBIE + 'Attack'

19 losthead_walk_name = c.NORMAL_ZOMBIE + 'LostHead'

20 losthead_attack_name = c.NORMAL_ZOMBIE + 'LostHeadAttack'

21 die_name = c.NORMAL_ZOMBIE + 'Die'

22

23 frame_list = [self.helmet_walk_frames, self.helmet_attack_frames,

24 self.walk_frames, self.attack_frames, self.losthead_walk_frames,

25 self.losthead_attack_frames, self.die_frames]

26 name_list = [helmet_walk_name, helmet_attack_name,

27 walk_name, attack_name, losthead_walk_name,

28 losthead_attack_name, die_name]

29

30 for i, name in enumerate(name_list):

31 self.loadFrames(frame_list[i], name, tool.ZOMBIE_RECT[name]['x'])

32

33 self.frames = self.helmet_walk_frames

以上就是这次python代码。注意:不管你是为了Python就业还是兴趣爱好,记住:项目开发经验永远是核心,如果你没有2020最新python入门到高级实战视频教程,可以去小编的Python交流.裙 :七衣衣九七七巴而五(数字的谐音)转换下可以找到了,里面很多新python教程项目,还可以跟老司机交流讨教!

本文的文字及图片来源于网络加上自己的想法,仅供学习、交流使用,不具有任何商业用途,版权归原作者所有,如有问题请及时联系我们以作处理。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值