From 14f485e8f5b478f9342895a6fed8601883fc795d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=98=9F=E5=A4=96=E4=B9=8B=E7=A5=9E?= Date: Fri, 29 Jul 2022 14:54:53 +0800 Subject: [PATCH] =?UTF-8?q?=E5=A2=9E=E5=8A=A0=E5=90=91=E6=97=A5=E8=91=B5?= =?UTF-8?q?=E5=A5=96=E6=9D=AF=E8=8E=B7=E5=BE=97=E7=95=8C=E9=9D=A2?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- pypvz.py | 2 +- source/constants.py | 1 + source/state/level.py | 56 ++++++++++++++++++---------------- source/state/screen.py | 68 +++++++++++++++++++++++++++--------------- source/tool.py | 3 +- 5 files changed, 78 insertions(+), 52 deletions(-) diff --git a/pypvz.py b/pypvz.py index e094c20..2d75121 100755 --- a/pypvz.py +++ b/pypvz.py @@ -16,7 +16,7 @@ if __name__=="__main__": if not os.path.exists(os.path.dirname(c.USERLOG_PATH)): os.makedirs(os.path.dirname(c.USERLOG_PATH)) logger = logging.getLogger("main") - formatter = logging.Formatter("%(asctime)s: %(message)s") + formatter = logging.Formatter("%(asctime)s - %(levelname)s: %(message)s") fileHandler = RotatingFileHandler(c.USERLOG_PATH, "a", 1024*1024, 0, "utf-8") fileHandler.setFormatter(formatter) streamHandler = logging.StreamHandler() diff --git a/source/constants.py b/source/constants.py index 2d9acf7..34d9526 100755 --- a/source/constants.py +++ b/source/constants.py @@ -95,6 +95,7 @@ LEVEL_PROGRESS_FLAG = "LevelProgressFlag" # GAME INFO字典键值 CURRENT_TIME = "current time" +PASSED_ALL = "passed all" # 已完成该模式下的所有游戏,应当显示向日葵奖杯获得界面 LEVEL_NUM = "level num" LITTLEGAME_NUM = "littleGame num" LEVEL_COMPLETIONS = "level completions" diff --git a/source/state/level.py b/source/state/level.py index 65c8113..a90e803 100644 --- a/source/state/level.py +++ b/source/state/level.py @@ -25,12 +25,11 @@ class Level(tool.State): self.showLittleMenu = False # 导入地图参数 - # 采用了容错设计,如果没有导入成功就不执行 - if self.loadMap(): # 表示导入成功 - self.map = map.Map(self.map_data[c.BACKGROUND_TYPE]) - self.map_y_len = self.map.height - self.setupBackground() - self.initState() + self.loadMap() + self.map = map.Map(self.map_data[c.BACKGROUND_TYPE]) + self.map_y_len = self.map.height + self.setupBackground() + self.initState() def saveUserData(self): with open(c.USERDATA_PATH, "w") as f: @@ -47,25 +46,19 @@ class Level(tool.State): if 0 <= self.game_info[c.LEVEL_NUM] < map.TOTAL_LEVEL: self.map_data = map.LEVEL_MAP_DATA[self.game_info[c.LEVEL_NUM]] else: - print("成功通关冒险模式!") self.game_info[c.LEVEL_NUM] = 1 - self.game_info[c.LEVEL_COMPLETIONS] += 1 - self.done = True - self.next = c.LEVEL self.saveUserData() - return + self.map_data = map.LEVEL_MAP_DATA[self.game_info[c.LEVEL_NUM]] + logger.warning("关卡数设定错误!进入默认的第一关!") # 小游戏模式 elif self.game_info[c.GAME_MODE] == c.MODE_LITTLEGAME: if 0 <= self.game_info[c.LITTLEGAME_NUM] < map.TOTAL_LITTLE_GAME: self.map_data = map.LITTLE_GAME_MAP_DATA[self.game_info[c.LITTLEGAME_NUM]] else: - print("成功通关玩玩小游戏!") self.game_info[c.LITTLEGAME_NUM] = 1 - self.game_info[c.LITTLEGAME_COMPLETIONS] += 1 - self.done = True - self.next = c.MAIN_MENU self.saveUserData() - return + self.map_data = map.LITTLE_GAME_MAP_DATA[self.game_info[c.LITTLEGAME_NUM]] + logger.warning("关卡数设定错误!进入默认的第一关!") # 是否有铲子的信息:无铲子时为0,有铲子时为1,故直接赋值即可 self.hasShovel = self.map_data[c.SHOVEL] @@ -90,8 +83,6 @@ class Level(tool.State): # 浓雾 elif self.map_data[c.BACKGROUND_TYPE] == c.BACKGROUND_FOG: self.bgm = 'fogLevel.opus' - # 表示成功加载地图 - return True def setupBackground(self): img_index = self.map_data[c.BACKGROUND_TYPE] @@ -152,7 +143,7 @@ class Level(tool.State): zombieList.append(newZombie) volume -= c.CREATE_ZOMBIE_DICT[newZombie][0] if volume < 0: - logger.warning(f'警告:第{wave}波中手动设置的僵尸级别总数超过上限!') + logger.warning(f'第{wave}波中手动设置的僵尸级别总数超过上限!') # 防止因为僵尸最小等级过大,使得总容量无法完全利用,造成死循环的检查机制 minCost = c.CREATE_ZOMBIE_DICT[min(useableZombies, key=lambda x:c.CREATE_ZOMBIE_DICT[x][0])][0] @@ -333,9 +324,6 @@ class Level(tool.State): # 更新函数每帧被调用,将鼠标事件传入给状态处理函数 def update(self, surface, current_time, mouse_pos, mouse_click): - # 这些内容是将来增加通过界面后的容错设计,以保证直接通关时不会闪退 - if self.done: - return self.current_time = self.game_info[c.CURRENT_TIME] = self.pvzTime(current_time) if self.state == c.CHOOSE: self.choose(mouse_pos, mouse_click) @@ -1433,14 +1421,30 @@ class Level(tool.State): def checkGameState(self): if self.checkVictory(): - if self.game_info[c.GAME_MODE] == c.MODE_LITTLEGAME: - self.game_info[c.LITTLEGAME_NUM] += 1 - elif self.game_info[c.GAME_MODE] == c.MODE_ADVENTURE: + # 播放胜利音效 + c.SOUND_WIN.play() + if self.game_info[c.GAME_MODE] == c.MODE_ADVENTURE: self.game_info[c.LEVEL_NUM] += 1 - self.next = c.GAME_VICTORY + if self.game_info[c.LEVEL_NUM] >= map.TOTAL_LEVEL: + self.game_info[c.LEVEL_COMPLETIONS] += 1 + self.game_info[c.LEVEL_NUM] = 1 + self.next = c.AWARD_SCREEN + else: + self.next = c.GAME_VICTORY + elif self.game_info[c.GAME_MODE] == c.MODE_LITTLEGAME: + self.game_info[c.LITTLEGAME_NUM] += 1 + if self.game_info[c.LITTLEGAME_NUM] > map.TOTAL_LITTLE_GAME: + self.game_info[c.LITTLEGAME_COMPLETIONS] += 1 + self.game_info[c.LITTLEGAME_NUM] = 1 + self.next = c.AWARD_SCREEN + else: + self.next = c.GAME_VICTORY self.done = True self.saveUserData() elif self.checkLose(): + # 播放失败音效 + c.SOUND_LOSE.play() + c.SOUND_SCREAM.play() self.next = c.GAME_LOSE self.done = True diff --git a/source/state/screen.py b/source/state/screen.py index 332ad1e..e511110 100644 --- a/source/state/screen.py +++ b/source/state/screen.py @@ -48,8 +48,6 @@ class GameVictoryScreen(Screen): self.setupImage(name) self.next = self.set_next_state() pg.display.set_caption("pypvz: 战斗胜利!") - # 播放胜利音效 - c.SOUND_WIN.play() class GameLoseScreen(Screen): def __init__(self): @@ -70,15 +68,12 @@ class GameLoseScreen(Screen): self.setupImage(name, (-15, 0, 800, 600)) self.next = self.set_next_state() pg.display.set_caption("pypvz: 战斗失败!") - # 播放失败音效 - c.SOUND_LOSE.play() - c.SOUND_SCREAM.play() class AwardScreen(tool.State): def __init__(self): tool.State.__init__(self) - def setupImage(self, gainedTrophy=True): + def setupImage(self): # 主体 frame_rect = (0, 0, 800, 600) self.image = tool.get_image(tool.GFX[c.AWARD_SCREEN_IMAGE], *frame_rect) @@ -97,53 +92,78 @@ class AwardScreen(tool.State): # 按钮 frame_rect = (0, 0, 111, 26) - if gainedTrophy: + if self.show_only_one_option: ## 主菜单按钮 - main_menu_button_image = tool.get_image(tool.GFX[c.UNIVERSAL_BUTTON], *frame_rect) - main_menu_button_image_rect = main_menu_button_image.get_rect() - main_menu_button_image_rect.x = 343 - main_menu_button_image_rect.y = 520 + self.main_menu_button_image = tool.get_image_menu(tool.GFX[c.UNIVERSAL_BUTTON], *frame_rect) + self.main_menu_button_image_rect = self.main_menu_button_image.get_rect() + self.main_menu_button_image_rect.x = 343 + self.main_menu_button_image_rect.y = 520 ### 主菜单按钮上的文字 font = pg.font.Font(c.FONT_PATH, 18) main_menu_text = font.render("主菜单", True, c.NAVYBLUE) main_menu_text_rect = main_menu_text.get_rect() main_menu_text_rect.x = 29 - main_menu_button_image.blit(main_menu_text, main_menu_text_rect) - self.image.blit(main_menu_button_image, main_menu_button_image_rect) + self.main_menu_button_image.blit(main_menu_text, main_menu_text_rect) + self.image.blit(self.main_menu_button_image, self.main_menu_button_image_rect) else: ## 继续按钮 - next_button_image = tool.get_image(tool.GFX[c.UNIVERSAL_BUTTON], *frame_rect) - next_button_image_rect = next_button_image.get_rect() - next_button_image_rect.x = 70 + self.next_button_image = tool.get_image_menu(tool.GFX[c.UNIVERSAL_BUTTON], *frame_rect) + self.next_button_image_rect = self.next_button_image.get_rect() + self.next_button_image_rect.x = 70 ### 继续按钮上的文字 font = pg.font.Font(c.FONT_PATH, 18) next_text = font.render("继续", True, c.NAVYBLUE) next_text_rect = next_text.get_rect() next_text_rect.x = 37 ## 主菜单按钮 - main_menu_button_image = tool.get_image(tool.GFX[c.UNIVERSAL_BUTTON], *frame_rect) - main_menu_button_image_rect = main_menu_button_image.get_rect() - main_menu_button_image_rect.x = 620 - next_button_image_rect.y = main_menu_button_image_rect.y = 540 + self.main_menu_button_image = tool.get_image_menu(tool.GFX[c.UNIVERSAL_BUTTON], *frame_rect) + self.main_menu_button_image_rect = self.main_menu_button_image.get_rect() + self.main_menu_button_image_rect.x = 620 + self.next_button_image_rect.y = self.main_menu_button_image_rect.y = 540 ### 主菜单按钮上的文字 main_menu_text = font.render("主菜单", True, c.NAVYBLUE) main_menu_text_rect = main_menu_text.get_rect() main_menu_text_rect.x = 29 - next_button_image.blit(next_text, next_text_rect) - main_menu_button_image.blit(main_menu_text, main_menu_text_rect) - self.image.blit(next_button_image, next_button_image_rect) - self.image.blit(main_menu_button_image, main_menu_button_image_rect) + self.next_button_image.blit(next_text, next_text_rect) + self.main_menu_button_image.blit(main_menu_text, main_menu_text_rect) + self.image.blit(self.next_button_image, self.next_button_image_rect) + self.image.blit(self.main_menu_button_image, self.main_menu_button_image_rect) + # 显示向日葵奖杯的情况 + if self.show_only_one_option: + if self.game_info[c.LITTLEGAME_COMPLETIONS]: + frame_rect = (157, 0, 157, 269) + else: + frame_rect = (0, 0, 157, 269) + sunflower_trophy_image = tool.get_image_menu(tool.GFX[c.TROPHY_SUNFLOWER], *frame_rect, scale=0.7) + sunflower_trophy_rect = sunflower_trophy_image.get_rect() + sunflower_trophy_rect.x = 348 + sunflower_trophy_rect.y = 110 + self.image.blit(sunflower_trophy_image, sunflower_trophy_rect) def startup(self, current_time, persist): self.start_time = current_time self.persist = persist self.game_info = persist + if (c.PASSED_ALL in self.game_info) and (not self.game_info[c.PASSED_ALL]): + self.show_only_one_option = False + else: + self.show_only_one_option = True self.setupImage() + pg.display.set_caption("pypvz: 您获得了新的战利品!") def update(self, surface, current_time, mouse_pos, mouse_click): surface.fill(c.WHITE) surface.blit(self.image, self.rect) + if mouse_pos: + # 检查主菜单点击 + if self.inArea(self.main_menu_button_image_rect, *mouse_pos): + self.next = c.MAIN_MENU + self.done = True + elif not self.show_only_one_option: + if self.inArea(self.next_button_image_rect, *mouse_pos): + self.next = c.LEVEL + self.done = True def inArea(self, rect, x, y): if (x >= rect.x and x <= rect.right and diff --git a/source/tool.py b/source/tool.py index 0396ab9..11829d1 100755 --- a/source/tool.py +++ b/source/tool.py @@ -130,6 +130,7 @@ class Control(): self.clock.tick(self.fps) def get_image(sheet, x, y, width, height, colorkey=c.BLACK, scale=1): + # 不保留alpha通道的图片导入 image = pg.Surface([width, height]) rect = image.get_rect() @@ -142,7 +143,7 @@ def get_image(sheet, x, y, width, height, colorkey=c.BLACK, scale=1): return image def get_image_menu(sheet, x, y, width, height, colorkey=c.BLACK, scale=1): - # 一定要保留阿尔法通道,修复主菜单bug,游戏中car显示又有bug + # 保留alpha通道的图片导入 image = pg.Surface([width, height], SRCALPHA) rect = image.get_rect()