"Reprint" Python Zombies code implementation (1): images load and display switch

In order to respect the original, this is the original link: Python Zombies code implementation (1): images load and display switch


Game description
picture display switching
image loading
complete code
code for
image loading
picture display switching
compiler environment
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, it themselves to write 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


figure 2


Picture display switch
2 can be seen from Figure 1 and Figure, 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 barrier
with barrier attack
without barricade traveling (i.e. becomes normal walking zombies)
without attacking barriers (i.e. becomes normal zombie attack)
without walking head
headless attack
deaths
FIG. 3 which is a barrier zombie example 7 kinds of picture types
of FIG. 3

Image loading
Zombies picture resources particularly comparing a picture type of each picture is a single action, FIG 4 is a barrier with a barrier zombie attack action photos, a total of 11 images, the loaded code image do corresponding modification.


The complete code for
a game code that implements the github link Zombies
here is the download link csdn Zombies

Code to achieve
here talk about the next image is loaded and pictures show the code switching, file directory structure and the entire game before Super Mario is the same.

Pictures loaded
in the source \ tool.py in load_all_gfx function iterates resources \ graphics directory and subdirectories.
Code made a simple distinction:

If resources \ graphics \ subfolder \ directory is a picture, a picture that is separate, such as resources \ graphics \ Screen directory interface picture
if the resources \ graphics \ subfolder \ directory is a subdirectory, then this subdirectory or All images belong to the sub-subdirectories a picture type, such as \ graphics \ zombies \ ConeheadZombie \ directory resources is under ConeheadZombieAttack barrier with barrier zombie attack action photos, as shown in FIG.

def load_all_gfx(directory, colorkey=c.WHITE, accept=('.png', '.jpg', '.bmp', '.gif')):
    graphics = {}
    for name1 in os.listdir(directory):
        # subfolders under the folder resources\graphics
        dir1 = os.path.join(directory, name1)
        if os.path.isdir(dir1):
            for name2 in os.listdir(dir1):
                dir2 = os.path.join(dir1, name2)
                if os.path.isdir(dir2):
                # e.g. subfolders under the folder resources\graphics\Zombies
                    for name3 in os.listdir(dir2):
                        dir3 = os.path.join(dir2, name3)
                        # e.g. subfolders or pics under the folder resources\graphics\Zombies\ConeheadZombie
                        if os.path.isdir(dir3):
                            # e.g. it's the folder resources\graphics\Zombies\ConeheadZombie\ConeheadZombieAttack
                            image_name, _ = os.path.splitext(name3)
                            graphics[image_name] = load_image_frames(dir3, image_name, colorkey, accept)
                        else:
                            # e.g. pics under the folder resources\graphics\Plants\Peashooter
                            image_name, _ = os.path.splitext(name2)
                            graphics[image_name] = load_image_frames(dir2, image_name, colorkey, accept)
                            break
                else:
                # e.g. pics under the folder resources\graphics\Screen
                    name, ext = os.path.splitext(name2)
                    if ext.lower() in accept:
                        img = pg.image.load(dir2)
                        if img.get_alpha():
                            img = img.convert_alpha()
                        else:
                            img = img.convert()
                            img.set_colorkey(colorkey)
                        graphics[name] = img
    return graphics

GFX = load_all_gfx(os.path.join("resources","graphics"))


load_image_frames function in accordance with all the pictures in the picture directory name in the index is key, stored in the tmp dictionary. For example, the image name is "ConeheadZombieAttack_2", its index value will be 2.
Photo By then sequentially added to the index value in frame_list.

def load_image_frames(directory, image_name, colorkey, accept):
    frame_list = []
    tmp = {}
    # image_name is "Peashooter", pic name is 'Peashooter_1', get the index 1
    index_start = len(image_name) + 1 
    frame_num = 0;
    for pic in os.listdir(directory):
        name, ext = os.path.splitext(pic)
        if ext.lower() in accept:
            index = int(name[index_start:])
            img = pg.image.load(os.path.join(directory, pic))
            if img.get_alpha():
                img = img.convert_alpha()
            else:
                img = img.convert()
                img.set_colorkey(colorkey)
            tmp[index]= img
            frame_num += 1

    for i in range(frame_num):
        frame_list.append(tmp[i])
    return frame_list


The basic functions are implemented in Zombie parent class, subclass that has special needs, you can redefine the function of the same name.

update function: Each entry will be called a tick function, used to update the position zombie, and a switching state display image update.
handleState function: to perform different functions according to the current state of the zombies.
animation functions: a motion picture is displayed under the type specified animate_interval every time.
  

    def update(self, game_info):
        self.current_time = game_info[c.CURRENT_TIME]
        self.handleState()
        self.animation()
    
    def handleState(self):
        if self.state == c.WALK:
            self.walking()
        elif self.state == c.ATTACK:
            self.attacking()
        elif self.state == c.DIE:
            self.dying()
    
    def animation(self):
        if (self.current_time - self.animate_timer) > self.animate_interval:
            self.frame_index += 1
            if self.frame_index >= self.frame_num:
                if self.state == c.DIE:
                    self.kill()
                    return
                self.frame_index = 0
            self.animate_timer = self.current_time
        
        self.image = self.frames[self.frame_index]


The following four functions are modified zombies and pictures show the current status.

setWalk functions: modify the walking state, the display image will be different depending on the image type setting values.
setAttack functions: modify the attack state, the display image will be different depending on the image type setting values.
setDie function: to modify the state of death.
changeFrames function: After modifying the type of picture, you need to reset the value of the member variable frame_num, frame_index, image and rect of.

    def setWalk(self):
        self.state = c.WALK
        self.animate_interval = 150
        
        if self.helmet:
            self.changeFrames(self.helmet_walk_frames)
        elif self.losHead:
            self.changeFrames(self.losthead_walk_frames)
        else:
            self.changeFrames(self.walk_frames)

    def setAttack(self, plant):
        self.plant = plant
        self.state = c.ATTACK
        self.animate_interval = 100
        
        if self.helmet:
            self.changeFrames(self.helmet_attack_frames)
        elif self.losHead:
            self.changeFrames(self.losthead_attack_frames)
        else:
            self.changeFrames(self.attack_frames)
    
    def setDie(self):
        self.state = c.DIE
        self.animate_interval = 200
        self.changeFrames(self.die_frames)
    
    def changeFrames(self, frames):
        '''change image frames and modify rect position'''
        self.frames = frames
        self.frame_num = len(self.frames)
        self.frame_index = 0
        
        bottom = self.rect.bottom
        centerx = self.rect.centerx
        self.image = self.frames[self.frame_index]
        self.rect = self.image.get_rect()
        self.rect.bottom = bottom
        self.rect.centerx = centerx


Roadblocks zombie is relatively simple, only need to implement loadImages function, call loadFrames function to load the kind of zombie supported image types, here the main difference is that the names of the different types of zombies will be different types of pictures.

class ConeHeadZombie(Zombie):
    def __init__(self, x, y, head_group):
        Zombie.__init__(self, x, y, c.CONEHEAD_ZOMBIE, c.CONEHEAD_HEALTH, head_group)
        self.helmet = True

    def loadImages(self):
        self.helmet_walk_frames = []
        self.helmet_attack_frames = []
        self.walk_frames = []
        self.attack_frames = []
        self.losthead_walk_frames = []
        self.losthead_attack_frames = []
        self.die_frames = []
        
        helmet_walk_name = self.name
        helmet_attack_name = self.name + 'Attack'
        walk_name = c.NORMAL_ZOMBIE
        attack_name = c.NORMAL_ZOMBIE + 'Attack'
        losthead_walk_name = c.NORMAL_ZOMBIE + 'LostHead'
        losthead_attack_name = c.NORMAL_ZOMBIE + 'LostHeadAttack'
        die_name = c.NORMAL_ZOMBIE + 'Die'

        frame_list = [self.helmet_walk_frames, self.helmet_attack_frames,
                      self.walk_frames, self.attack_frames, self.losthead_walk_frames,
                      self.losthead_attack_frames, self.die_frames]
        name_list = [helmet_walk_name, helmet_attack_name,
                     walk_name, attack_name, losthead_walk_name,
                     losthead_attack_name, die_name]
        
        for i, name in enumerate(name_list):
            self.loadFrames(frame_list[i], name, tool.ZOMBIE_RECT[name]['x'])

        self.frames = self.helmet_walk_frames


Compiler environment
python3.7 + pygame1.9
 

Published 91 original articles · won praise 47 · views 90000 +

Guess you like

Origin blog.csdn.net/qq_30007885/article/details/104443809