Pygame多关卡游戏如何实现退出后从上次关卡续玩
Pygame关卡进度续玩功能实现方案
核心逻辑是通过本地轻量存档文件持久化存储玩家的最新关卡进度,游戏启动时自动读取存档,PLAY按钮不再固定跳转第1关,而是直接跳转到存档记录的关卡。
1. 新增依赖导入和进度读写工具
在代码开头的导入区新增两个Python标准库导入,不需要安装第三方依赖:
import json import os
在全局常量区新增关卡映射、存档路径配置,以及两个进度操作函数:
# 关卡入口函数映射,索引0对应第1关,以此类推 LEVEL_ENTRANCES = [main1, main2, main3, main4, main5, main6, main7, main8, main9, main10, main11, main12] SAVE_FILE_PATH = "game_progress.json" def load_saved_level(): """读取本地存档,返回上次解锁的最新关卡,默认返回1""" # 存档不存在直接返回第1关 if not os.path.exists(SAVE_FILE_PATH): return 1 try: with open(SAVE_FILE_PATH, "r", encoding="utf-8") as f: progress = json.load(f) saved_level = progress.get("latest_level", 1) # 边界校验,防止存档损坏导致关卡号越界 return max(1, min(12, saved_level)) except: # 存档读取异常时默认从第1关启动 return 1 def save_progress(current_level: int): """将当前关卡号写入本地存档""" # 如果需要保留最高解锁记录(手动选低关卡不覆盖进度),放开下面两行注释 # saved_max = load_saved_level() # if current_level <= saved_max: # return progress_data = {"latest_level": current_level} with open(SAVE_FILE_PATH, "w", encoding="utf-8") as f: json.dump(progress_data, f)
2. 修改主菜单PLAY按钮逻辑
找到main_menu()函数中PLAY按钮的点击判断代码,把原来固定调用main1()的逻辑替换为读取存档后跳转对应关卡:
if PLAY_BUTTON.checkForInput(MENU_MOUSE_POS): pygame.mixer.music.play() target_level = load_saved_level() LEVEL_ENTRANCES[target_level - 1]()
3. 修改关卡选择界面的点击逻辑
玩家手动选择任意关卡进入时,先把选中的关卡写入存档,再启动对应关卡。比如原来LEVEL1按钮的点击逻辑:
if level1.checkForInput(OPTIONS_MOUSE_POS): pygame.mixer.music.play() main1()
修改为:
if level1.checkForInput(OPTIONS_MOUSE_POS): pygame.mixer.music.play() save_progress(1) main1()
剩下LEVEL2到LEVEL12的点击逻辑按同样规则修改,把save_progress的参数换成对应关卡编号即可。
4. 补充关卡内的进度存储逻辑
- 关卡通关自动跳转下一关时,在调用下一关的入口函数前,先执行
save_progress(下一关编号),保证玩家推进关卡时进度实时更新。 - 每个关卡的事件循环中,检测到
pygame.QUIT事件(玩家点窗口关闭按钮)、返回主菜单事件时,先执行save_progress(当前关卡编号),再执行退出/返回逻辑,避免玩家中途退出时进度丢失。
可选优化:消除重复代码
当前关卡选择界面的12个按钮创建、点击判断代码重复度极高,可以用循环简化,后续修改按钮样式、位置只需要改一次:
def level(): pygame.display.set_caption("Levels") pygame.mixer.music.play() # 提前加载一次音效,避免每帧重复加载卡顿 click_sound = pygame.mixer.Sound("click sound.wav") while True: OPTIONS_MOUSE_POS = pygame.mouse.get_pos() SCREEN.fill((3, 54, 73)) level_buttons = [] # 循环生成12个关卡按钮 for level_idx in range(12): x_pos = 320 if level_idx < 6 else 960 y_pos = 60 + (level_idx % 6) * 100 btn = Button( image=pygame.image.load("button.png"), font=pygame.font.SysFont("Roboto", 60), pos=(x_pos, y_pos), text_input=f"LEVEL {level_idx+1}", base_color="white", hovering_color=(0, 204, 0), music=click_sound ) btn.changeColor(OPTIONS_MOUSE_POS) btn.update(SCREEN) level_buttons.append(btn) for event in pygame.event.get(): if event.type == pygame.QUIT: pygame.mixer.music.play() main_menu() if event.type == pygame.MOUSEBUTTONDOWN: # 循环检测按钮点击 for idx, btn in enumerate(level_buttons): if btn.checkForInput(OPTIONS_MOUSE_POS): pygame.mixer.music.play() target_level = idx + 1 save_progress(target_level) LEVEL_ENTRANCES[idx]() break pygame.display.update()
内容的提问来源于stack exchange,提问作者haider shah
相关产品推荐
相关产品推荐

