• Python版【植物大战僵尸 +源码】


    写在前面:

    今天给大家推荐一个Gtihub开源项目:PythonPlantsVsZombies,翻译成中就是植物大战僵尸。

    在这里插入图片描述

    植物大战僵尸》是一款极富策略性的小游戏。可怕的僵尸即将入侵,每种僵尸都有不同的特点,例如铁桶僵尸拥有极强的抗击打能力,矿工僵尸可以挖地道绕过种植在土壤表面的植物等。玩家防御僵尸的方式就是栽种植物。49种植物每种都有不同的功能,例如樱桃炸弹可以和周围一定范围内的所有僵尸同归于尽,而食人花可以吃掉最靠近自己的一只僵尸。玩家可以针对不同僵尸的弱点来合理地种植植物,这也是胜利的诀窍。游戏根据玩法不同分为五种游戏模式:冒险模式、迷你模式、解谜模式、生存模式、禅境花园。加之黑夜、屋顶、浓雾以及泳池之类的障碍增加了其挑战性。该游戏近乎永无止境。

    功能实现

    • 支持的植物:向日葵、豌豆射手、胡桃、雪豌豆射手、樱桃炸弹、三豌豆射手、大嘴花、puffshroom、马铃薯胺、穗状杂草、南瓜、胆小菇、墨西哥胡椒、阳光菇、冰川菇、催眠蘑菇。

    • 支持僵尸:普通僵尸,旗帜僵尸,路障僵尸,铁桶僵尸,报纸僵尸。

    • 支持在关卡开始时选择植物卡片。

    • 支持白天级别、夜间级别、移动卡选择级别和胡桃保龄球级别。

    环境要求

    • 1、python3.7
      注意: Python3.7是最佳运行环境,但是不是强制性要求。对于Linux: 如果你的 Linux 有预装的 Python3+ 就可以运行了。LINUX Mint 操作系统直接升级到 Python 3.7 有可能导致系统自带的 python 版本无法执行。

    • 2、Python-Pygame 1.9

    怎么玩

    使用鼠标收集阳光,选择植物卡片并播种植物
    您可以通过更改 source/constants.py 中的START_LEVEL_NUM值来设置起始级别
    级别 1 和 2:天级别
    第 3 级:夜间级别
    第 4 级:移动卡片选择级别
    5级:墙果保龄球级别

    个性化定义

    游戏的关卡数据,存储在json文件里的。具体目录:PythonPlantsVsZombies-master\source\data。我们可以进行自定义配置,例如僵尸的位置和时间,背景信息。

    在这里插入图片描述

    项目演示:

    在这里插入图片描述
    在这里插入图片描述

    源码分享

    Map地图:

    __author__ = 'marble_xu'
    
    import random
    import pygame as pg
    from .. import tool
    from .. import constants as c
    
    class Map():
        def __init__(self, width, height):
            self.width = width
            self.height = height
            self.map = [[0 for x in range(self.width)] for y in range(self.height)]
    
        def isValid(self, map_x, map_y):
            if (map_x < 0 or map_x >= self.width or
                map_y < 0 or map_y >= self.height):
                return False
            return True
        
        def isMovable(self, map_x, map_y):
            return (self.map[map_y][map_x] == c.MAP_EMPTY)
        
        def getMapIndex(self, x, y):
            x -= c.MAP_OFFSET_X
            y -= c.MAP_OFFSET_Y
            return (x // c.GRID_X_SIZE, y // c.GRID_Y_SIZE)
        
        def getMapGridPos(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)
        
        def setMapGridType(self, map_x, map_y, type):
            self.map[map_y][map_x] = type
    
        def getRandomMapIndex(self):
            map_x = random.randint(0, self.width-1)
            map_y = random.randint(0, self.height-1)
            return (map_x, map_y)
    
        def showPlant(self, x, y):
            pos = None
            map_x, map_y = self.getMapIndex(x, y)
            if self.isValid(map_x, map_y) and self.isMovable(map_x, map_y):
                pos = self.getMapGridPos(map_x, map_y)
            return pos
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45

    Menubar.py

    __author__ = 'marble_xu'
    
    import random
    import pygame as pg
    from .. import tool
    from .. import constants as c
    
    PANEL_Y_START = 87
    PANEL_X_START = 22
    PANEL_Y_INTERNAL = 74
    PANEL_X_INTERNAL = 53
    CARD_LIST_NUM = 8
    
    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_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]
    
    def getSunValueImage(sun_value):
        font = pg.font.SysFont(None, 22)
        width = 32
        msg_image = font.render(str(sun_value), True, c.NAVYBLUE, c.LIGHTYELLOW)
        msg_rect = msg_image.get_rect()
        msg_w = msg_rect.width
    
        image = pg.Surface([width, 17])
        x = width - msg_w
    
        image.fill(c.LIGHTYELLOW)
        image.blit(msg_image, (x, 0), (0, 0, msg_rect.w, msg_rect.h))
        image.set_colorkey(c.BLACK)
        return image
    
    def getCardPool(data):
        card_pool = []
        for card in data:
            tmp = card['name']
            for i,name in enumerate(plant_name_list):
                if name == tmp:
                    card_pool.append(i)
                    break
        return card_pool
    
    class Card():
        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 = x
            self.rect.y = y
            
            self.name_index = name_index
            self.sun_cost = plant_sun_list[name_index]
            self.frozen_time = plant_frozen_time_list[name_index]
            self.frozen_timer = -self.frozen_time
            self.refresh_timer = 0
            self.select = True
    
        def loadFrame(self, name, scale):
            frame = tool.GFX[name]
            rect = frame.get_rect()
            width, height = rect.w, rect.h
    
            self.orig_image = tool.get_image(frame, 0, 0, width, height, c.BLACK, scale)
            self.image = self.orig_image
    
        def checkMouseClick(self, mouse_pos):
            x, y = mouse_pos
            if(x >= self.rect.x and x <= self.rect.right and
               y >= self.rect.y and y <= self.rect.bottom):
                return True
            return False
    
        def canClick(self, sun_value, current_time):
            if self.sun_cost <= sun_value and (current_time - self.frozen_timer) > self.frozen_time:
                return True
            return False
    
        def canSelect(self):
            return self.select
    
        def setSelect(self, can_select):
            self.select = can_select
            if can_select:
                self.image.set_alpha(255)
            else:
                self.image.set_alpha(128)
    
        def setFrozenTime(self, current_time):
            self.frozen_timer = current_time
    
        def createShowImage(self, sun_value, current_time):
            '''create a card image to show cool down status
               or disable status when have not enough sun value'''
            time = current_time - self.frozen_timer
            if time < self.frozen_time: #cool down status
                image = pg.Surface([self.rect.w, self.rect.h])
                frozen_image = self.orig_image.copy()
                frozen_image.set_alpha(128)
                frozen_height = (self.frozen_time - time)/self.frozen_time * self.rect.h
                
                image.blit(frozen_image, (0,0), (0, 0, self.rect.w, frozen_height))
                image.blit(self.orig_image, (0,frozen_height),
                           (0, frozen_height, self.rect.w, self.rect.h - frozen_height))
            elif self.sun_cost > sun_value: #disable status
                image = self.orig_image.copy()
                image.set_alpha(192)
            else:
                image = self.orig_image
            return image
    
        def update(self, sun_value, current_time):
            if (current_time - self.refresh_timer) >= 250:
                self.image = self.createShowImage(sun_value, current_time)
                self.refresh_timer = current_time
    
        def draw(self, surface):
            surface.blit(self.image, self.rect)
    
    class MenuBar():
        def __init__(self, card_list, sun_value):
            self.loadFrame(c.MENUBAR_BACKGROUND)
            self.rect = self.image.get_rect()
            self.rect.x = 10
            self.rect.y = 0
            
            self.sun_value = sun_value
            self.card_offset_x = 32
            self.setupCards(card_list)
    
        def loadFrame(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)
    
        def update(self, current_time):
            self.current_time = current_time
            for card in self.card_list:
                card.update(self.sun_value, self.current_time)
    
        def createImage(self, x, y, num):
            if num == 1:
                return
            img = self.image
            rect = self.image.get_rect()
            width = rect.w
            height = rect.h
            self.image = pg.Surface((width * num, height)).convert()
            self.rect = self.image.get_rect()
            self.rect.x = x
            self.rect.y = y
            for i in range(num):
                x = i * width
                self.image.blit(img, (x,0))
            self.image.set_colorkey(c.BLACK)
        
        def setupCards(self, card_list):
            self.card_list = []
            x = self.card_offset_x
            y = 8
            for index in card_list:
                x += 55
                self.card_list.append(Card(x, y, index))
    
        def checkCardClick(self, mouse_pos):
            result = None
            for card in self.card_list:
                if card.checkMouseClick(mouse_pos):
                    if card.canClick(self.sun_value, self.current_time):
                        result = (plant_name_list[card.name_index], card)
                    break
            return result
        
        def checkMenuBarClick(self, mouse_pos):
            x, y = mouse_pos
            if(x >= self.rect.x and x <= self.rect.right and
               y >= self.rect.y and y <= self.rect.bottom):
                return True
            return False
    
        def decreaseSunValue(self, value):
            self.sun_value -= value
    
        def increaseSunValue(self, value):
            self.sun_value += value
    
        def setCardFrozenTime(self, plant_name):
            for card in self.card_list:
                if plant_name_list[card.name_index] == plant_name:
                    card.setFrozenTime(self.current_time)
                    break
    
        def drawSunValue(self):
            self.value_image = getSunValueImage(self.sun_value)
            self.value_rect = self.value_image.get_rect()
            self.value_rect.x = 21
            self.value_rect.y = self.rect.bottom - 21
            
            self.image.blit(self.value_image, self.value_rect)
    
        def draw(self, surface):
            self.drawSunValue()
            surface.blit(self.image, self.rect)
            for card in self.card_list:
                card.draw(surface)
    
    class Panel():
        def __init__(self, card_list, sun_value):
            self.loadImages(sun_value)
            self.selected_cards = []
            self.selected_num = 0
            self.setupCards(card_list)
    
        def loadFrame(self, name):
            frame = tool.GFX[name]
            rect = frame.get_rect()
            frame_rect = (rect.x, rect.y, rect.w, rect.h)
    
            return tool.get_image(tool.GFX[name], *frame_rect, c.WHITE, 1)
    
        def loadImages(self, sun_value):
            self.menu_image = self.loadFrame(c.MENUBAR_BACKGROUND)
            self.menu_rect = self.menu_image.get_rect()
            self.menu_rect.x = 0
            self.menu_rect.y = 0
    
            self.panel_image = self.loadFrame(c.PANEL_BACKGROUND)
            self.panel_rect = self.panel_image.get_rect()
            self.panel_rect.x = 0
            self.panel_rect.y = PANEL_Y_START
    
            
            self.value_image = getSunValueImage(sun_value)
            self.value_rect = self.value_image.get_rect()
            self.value_rect.x = 21
            self.value_rect.y = self.menu_rect.bottom - 21
    
            self.button_image =  self.loadFrame(c.START_BUTTON)
            self.button_rect = self.button_image.get_rect()
            self.button_rect.x = 155
            self.button_rect.y = 547
    
        def setupCards(self, card_list):
            self.card_list = []
            x = PANEL_X_START - PANEL_X_INTERNAL
            y = PANEL_Y_START + 43 - PANEL_Y_INTERNAL
            for i, index in enumerate(card_list):
                if i % 8 == 0:
                    x = PANEL_X_START - PANEL_X_INTERNAL
                    y += PANEL_Y_INTERNAL
                x += PANEL_X_INTERNAL
                self.card_list.append(Card(x, y, index, 0.75))
    
        def checkCardClick(self, mouse_pos):
            delete_card = None
            for card in self.selected_cards:
                if delete_card: # when delete a card, move right cards to left
                    card.rect.x -= 55
                elif card.checkMouseClick(mouse_pos):
                    self.deleteCard(card.name_index)
                    delete_card = card
    
            if delete_card:
                self.selected_cards.remove(delete_card)
                self.selected_num -= 1
    
            if self.selected_num == CARD_LIST_NUM:
                return
    
            for card in self.card_list:
                if card.checkMouseClick(mouse_pos):
                    if card.canSelect():
                        self.addCard(card)
                    break
    
        def addCard(self, card):
            card.setSelect(False)
            y = 8
            x = 78 + self.selected_num * 55
            self.selected_cards.append(Card(x, y, card.name_index))
            self.selected_num += 1
    
        def deleteCard(self, index):
            self.card_list[index].setSelect(True)
    
        def checkStartButtonClick(self, mouse_pos):
            if self.selected_num < CARD_LIST_NUM:
                return False
    
            x, y = mouse_pos
            if (x >= self.button_rect.x and x <= self.button_rect.right and
                y >= self.button_rect.y and y <= self.button_rect.bottom):
               return True
            return False
    
        def getSelectedCards(self):
            card_index_list = []
            for card in self.selected_cards:
                card_index_list.append(card.name_index)
            return card_index_list
    
        def draw(self, surface):
            self.menu_image.blit(self.value_image, self.value_rect)
            surface.blit(self.menu_image, self.menu_rect)
            surface.blit(self.panel_image, self.panel_rect)
            for card in self.card_list:
                card.draw(surface)
            for card in self.selected_cards:
                card.draw(surface)
    
            if self.selected_num == CARD_LIST_NUM:
                surface.blit(self.button_image, self.button_rect)
    
    class MoveCard():
        def __init__(self, x, y, card_name, plant_name, scale=0.78):
            self.loadFrame(card_name, scale)
            self.rect = self.orig_image.get_rect()
            self.rect.x = x
            self.rect.y = y
            self.rect.w = 1
            self.image = self.createShowImage()
    
            self.card_name = card_name
            self.plant_name = plant_name
            self.move_timer = 0
            self.select = True
    
        def loadFrame(self, name, scale):
            frame = tool.GFX[name]
            rect = frame.get_rect()
            width, height = rect.w, rect.h
    
            self.orig_image = tool.get_image(frame, 0, 0, width, height, c.BLACK, scale)
            self.orig_rect = self.orig_image.get_rect()
            self.image = self.orig_image
    
        def checkMouseClick(self, mouse_pos):
            x, y = mouse_pos
            if(x >= self.rect.x and x <= self.rect.right and
               y >= self.rect.y and y <= self.rect.bottom):
                return True
            return False
    
        def createShowImage(self):
            '''create a part card image when card appears from left'''
            if self.rect.w < self.orig_rect.w: #create a part card image
                image = pg.Surface([self.rect.w, self.rect.h])
                image.blit(self.orig_image, (0, 0), (0, 0, self.rect.w, self.rect.h))
                self.rect.w += 1
            else:
                image = self.orig_image
            return image
    
        def update(self, left_x, current_time):
            if self.move_timer == 0:
                self.move_timer = current_time
            elif (current_time - self.move_timer) >= c.CARD_MOVE_TIME:
                if self.rect.x > left_x:
                    self.rect.x -= 1
                    self.image = self.createShowImage()
                self.move_timer += c.CARD_MOVE_TIME
    
        def draw(self, surface):
            surface.blit(self.image, self.rect)
    
    class MoveBar():
        def __init__(self, card_pool):
            self.loadFrame(c.MOVEBAR_BACKGROUND)
            self.rect = self.image.get_rect()
            self.rect.x = 90
            self.rect.y = 0
            
            self.card_start_x = self.rect.x + 8
            self.card_end_x = self.rect.right - 5
            self.card_pool = card_pool
            self.card_list = []
            self.create_timer = -c.MOVEBAR_CARD_FRESH_TIME
    
        def loadFrame(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)
    
        def createCard(self):
            if len(self.card_list) > 0 and self.card_list[-1].rect.right > self.card_end_x:
                return False
            x = self.card_end_x
            y = 6
            index = 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))
            return True
    
        def update(self, current_time):
            self.current_time = current_time
            left_x = self.card_start_x
            for card in self.card_list:
                card.update(left_x, self.current_time)
                left_x = card.rect.right + 1
    
            if(self.current_time - self.create_timer) > c.MOVEBAR_CARD_FRESH_TIME:
                if self.createCard():
                    self.create_timer = self.current_time
    
        def checkCardClick(self, mouse_pos):
            result = None
            for index, card in enumerate(self.card_list):
                if card.checkMouseClick(mouse_pos):
                    result = (card.plant_name, card)
                    break
            return result
        
        def checkMenuBarClick(self, mouse_pos):
            x, y = mouse_pos
            if(x >= self.rect.x and x <= self.rect.right and
               y >= self.rect.y and y <= self.rect.bottom):
                return True
            return False
    
        def deleateCard(self, card):
            self.card_list.remove(card)
    
        def draw(self, surface):
            surface.blit(self.image, self.rect)
            for card in self.card_list:
                card.draw(surface)
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67
    • 68
    • 69
    • 70
    • 71
    • 72
    • 73
    • 74
    • 75
    • 76
    • 77
    • 78
    • 79
    • 80
    • 81
    • 82
    • 83
    • 84
    • 85
    • 86
    • 87
    • 88
    • 89
    • 90
    • 91
    • 92
    • 93
    • 94
    • 95
    • 96
    • 97
    • 98
    • 99
    • 100
    • 101
    • 102
    • 103
    • 104
    • 105
    • 106
    • 107
    • 108
    • 109
    • 110
    • 111
    • 112
    • 113
    • 114
    • 115
    • 116
    • 117
    • 118
    • 119
    • 120
    • 121
    • 122
    • 123
    • 124
    • 125
    • 126
    • 127
    • 128
    • 129
    • 130
    • 131
    • 132
    • 133
    • 134
    • 135
    • 136
    • 137
    • 138
    • 139
    • 140
    • 141
    • 142
    • 143
    • 144
    • 145
    • 146
    • 147
    • 148
    • 149
    • 150
    • 151
    • 152
    • 153
    • 154
    • 155
    • 156
    • 157
    • 158
    • 159
    • 160
    • 161
    • 162
    • 163
    • 164
    • 165
    • 166
    • 167
    • 168
    • 169
    • 170
    • 171
    • 172
    • 173
    • 174
    • 175
    • 176
    • 177
    • 178
    • 179
    • 180
    • 181
    • 182
    • 183
    • 184
    • 185
    • 186
    • 187
    • 188
    • 189
    • 190
    • 191
    • 192
    • 193
    • 194
    • 195
    • 196
    • 197
    • 198
    • 199
    • 200
    • 201
    • 202
    • 203
    • 204
    • 205
    • 206
    • 207
    • 208
    • 209
    • 210
    • 211
    • 212
    • 213
    • 214
    • 215
    • 216
    • 217
    • 218
    • 219
    • 220
    • 221
    • 222
    • 223
    • 224
    • 225
    • 226
    • 227
    • 228
    • 229
    • 230
    • 231
    • 232
    • 233
    • 234
    • 235
    • 236
    • 237
    • 238
    • 239
    • 240
    • 241
    • 242
    • 243
    • 244
    • 245
    • 246
    • 247
    • 248
    • 249
    • 250
    • 251
    • 252
    • 253
    • 254
    • 255
    • 256
    • 257
    • 258
    • 259
    • 260
    • 261
    • 262
    • 263
    • 264
    • 265
    • 266
    • 267
    • 268
    • 269
    • 270
    • 271
    • 272
    • 273
    • 274
    • 275
    • 276
    • 277
    • 278
    • 279
    • 280
    • 281
    • 282
    • 283
    • 284
    • 285
    • 286
    • 287
    • 288
    • 289
    • 290
    • 291
    • 292
    • 293
    • 294
    • 295
    • 296
    • 297
    • 298
    • 299
    • 300
    • 301
    • 302
    • 303
    • 304
    • 305
    • 306
    • 307
    • 308
    • 309
    • 310
    • 311
    • 312
    • 313
    • 314
    • 315
    • 316
    • 317
    • 318
    • 319
    • 320
    • 321
    • 322
    • 323
    • 324
    • 325
    • 326
    • 327
    • 328
    • 329
    • 330
    • 331
    • 332
    • 333
    • 334
    • 335
    • 336
    • 337
    • 338
    • 339
    • 340
    • 341
    • 342
    • 343
    • 344
    • 345
    • 346
    • 347
    • 348
    • 349
    • 350
    • 351
    • 352
    • 353
    • 354
    • 355
    • 356
    • 357
    • 358
    • 359
    • 360
    • 361
    • 362
    • 363
    • 364
    • 365
    • 366
    • 367
    • 368
    • 369
    • 370
    • 371
    • 372
    • 373
    • 374
    • 375
    • 376
    • 377
    • 378
    • 379
    • 380
    • 381
    • 382
    • 383
    • 384
    • 385
    • 386
    • 387
    • 388
    • 389
    • 390
    • 391
    • 392
    • 393
    • 394
    • 395
    • 396
    • 397
    • 398
    • 399
    • 400
    • 401
    • 402
    • 403
    • 404
    • 405
    • 406
    • 407
    • 408
    • 409
    • 410
    • 411
    • 412
    • 413
    • 414
    • 415
    • 416
    • 417
    • 418
    • 419
    • 420
    • 421
    • 422
    • 423
    • 424
    • 425
    • 426
    • 427
    • 428
    • 429
    • 430
    • 431
    • 432
    • 433
    • 434
    • 435
    • 436
    • 437
    • 438
    • 439
    • 440
    • 441

    主菜单

    __author__ = 'marble_xu'
    
    import pygame as pg
    from .. import tool
    from .. import constants as c
    
    class Menu(tool.State):
        def __init__(self):
            tool.State.__init__(self)
        
        def startup(self, current_time, persist):
            self.next = c.LEVEL
            self.persist = persist
            self.game_info = persist
            
            self.setupBackground()
            self.setupOption()
    
        def setupBackground(self):
            frame_rect = [80, 0, 800, 600]
            self.bg_image = tool.get_image(tool.GFX[c.MAIN_MENU_IMAGE], *frame_rect)
            self.bg_rect = self.bg_image.get_rect()
            self.bg_rect.x = 0
            self.bg_rect.y = 0
            
        def setupOption(self):
            self.option_frames = []
            frame_names = [c.OPTION_ADVENTURE + '_0', c.OPTION_ADVENTURE + '_1']
            frame_rect = [0, 0, 165, 77]
            
            for name in frame_names:
                self.option_frames.append(tool.get_image(tool.GFX[name], *frame_rect, c.BLACK, 1.7))
            
            self.option_frame_index = 0
            self.option_image = self.option_frames[self.option_frame_index]
            self.option_rect = self.option_image.get_rect()
            self.option_rect.x = 435
            self.option_rect.y = 75
            
            self.option_start = 0
            self.option_timer = 0
            self.option_clicked = False
        
        def checkOptionClick(self, mouse_pos):
            x, y = mouse_pos
            if(x >= self.option_rect.x and x <= self.option_rect.right and
               y >= self.option_rect.y and y <= self.option_rect.bottom):
                self.option_clicked = True
                self.option_timer = self.option_start = self.current_time
            return False
            
        def update(self, surface, current_time, mouse_pos, mouse_click):
            self.current_time = self.game_info[c.CURRENT_TIME] = current_time
            
            if not self.option_clicked:
                if mouse_pos:
                    self.checkOptionClick(mouse_pos)
            else:
                if(self.current_time - self.option_timer) > 200:
                    self.option_frame_index += 1
                    if self.option_frame_index >= 2:
                        self.option_frame_index = 0
                    self.option_timer = self.current_time
                    self.option_image = self.option_frames[self.option_frame_index]
                if(self.current_time - self.option_start) > 1300:
                    self.done = True
    
            surface.blit(self.bg_image, self.bg_rect)
            surface.blit(self.option_image, self.option_rect)
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67
    • 68
    • 69

    主函数:

    __author__ = 'marble_xu'
    
    from . import tool
    from . import constants as c
    from .state import mainmenu, screen, level
    
    def main():
        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()
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14

    项目开源地址

    https://github.com/marblexu/PythonPlantsVsZombies

  • 相关阅读:
    v4l2-ctl基本使用方法
    [Blender] Blender 获取 Instance 的信息
    Python接口自动化实战案例
    【C++进阶】多态
    【2022 Twitter爬虫高级搜索接口分析及代码编写 Python爬虫 附主要代码及解析】
    智能的花火,照亮一座5G钢铁工厂的时代之舞
    集合线程执行
    一致性 Hash 算法
    GD32F103x 定时器
    Unity SteamVR 开发教程:用摇杆/触摸板控制人物持续移动(2.x 以上版本)
  • 原文地址:https://blog.csdn.net/m0_68089732/article/details/137202714