Zombies Python code to achieve: switch to load and display pictures

The game is introduced
before the fire Zombies game, I wanted to find in the online version of the game under the python to learn, but unfortunately did not find relatively complete, then write yourself a put. Picture resource is downloaded from github because of the limited resources picture, can only be achieved in several plants and zombies.
Function to achieve the following:

Supported plant type: sunflowers, pea shooter, Ice shooter, nuts, cherry bombs. The new increase plant: pea shooter double, triple pea shooter.
Supported zombie type: zombies, zombie pawn, roadblocks zombie, zombie drum.
Use json file saved checkpoint information, set the time and location of zombies appear.
The new increase weeder.
Below is a screenshot of the game:
1

demo2

                                                                                              figure 2

 

 

 

Image display switching


As seen in Figure 1 and Figure 2, the picture zombie walking and attacking display will be different, this article about how to switch next picture shows.
To the above roadblocks zombie, for example, a total of the following types of image types.

  • Walking with barricade
  • With roadblocks attack
  • Walk without barricade (i.e. becomes normal walking zombies)
  • Without roadblocks attack (ie, become ordinary zombie attack)
  • Walking without a head
  • No head attack
  • death

3 is an example of these seven roadblocks zombie picture type

 

Image loading

Zombies resources rather special picture a picture of each type of action is a single image, Figure 4 is a roadblock roadblocks zombie attack with action photos, a total of 11 images, so the code to do loads of picture corresponding changes.

 

 

The complete code

Game code that implements the github link  Zombies
here is the download link csdn  Zombies

图片加载
在 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

Watch the video to learn the discussion group: 887 934 385 source code, and related material

Compiler Environment

python3.7 + pygame1.9

Watch the video to learn the discussion group: 887 934 385 source code, and related material

Guess you like

Origin www.cnblogs.com/pypypy/p/12158437.html