You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Python Pygame开发:游戏菜单无法显示问题求助

问题排查:Lunar Dungeon菜单无法显示的原因及修复方案

嘿,我来帮你看看菜单不显示的问题!仔细梳理你的代码后,找到了核心问题和几个需要调整的细节,具体如下:

核心原因:菜单逻辑从未被触发

你在代码后半部分定义了Game类,但从头到尾都没有创建这个类的实例,也没有启动菜单的显示逻辑。而且前面的while running循环是无限运行的(直到你关闭窗口),这就导致后面的Game类代码完全没机会被执行——程序一直卡在蓝色背景的循环里,菜单自然不会出现。

其他需要修正的细节

  • 重复初始化Pygame:代码开头已经调用了pygame.init(),但Game类的__init__里又重复调用,会造成冗余甚至潜在问题。
  • 窗口大小不一致:开头创建的窗口是1080x720,但Game类里又创建了480x270的窗口,会导致窗口切换混乱。
  • 缺少菜单基础类:Game类里引用了MainMenu、OptionsMenu、CreditsMenu,但代码里没有定义这些类,就算启动菜单也会报错。

修复后的完整代码

我帮你调整了代码,解决了上述问题,现在菜单可以正常显示并交互了:

import pygame
import sys

# 初始化Pygame(只做一次)
pygame.init()
print(pygame.ver)

# 定义菜单基础类(Game类依赖这些,必须补上)
class Menu():
    def __init__(self, game):
        self.game = game
        self.run_display = True
        self.cursor_rect = pygame.Rect(0, 0, 20, 20)
        self.offset = -100

    def draw_cursor(self):
        self.game.draw_text('>', 15, self.cursor_rect.x, self.cursor_rect.y)

    def blit_screen(self):
        self.game.window.blit(self.game.display, (0, 0))
        pygame.display.update()
        self.game.reset_keys()

class MainMenu(Menu):
    def __init__(self, game):
        Menu.__init__(self, game)
        self.state = "Start"
        self.startx, self.starty = self.game.DISPLAY_W/2, self.game.DISPLAY_H/2 - 40
        self.optionsx, self.optionsy = self.game.DISPLAY_W/2, self.game.DISPLAY_H/2
        self.creditsx, self.creditsy = self.game.DISPLAY_W/2, self.game.DISPLAY_H/2 + 40
        self.cursor_rect.midtop = (self.startx + self.offset, self.starty)

    def display_menu(self):
        self.run_display = True
        while self.run_display:
            self.game.check_events()
            self.check_input()
            self.game.display.fill(self.game.BLACK)
            self.game.draw_text('LUNAR DUNGEON', 25, self.game.DISPLAY_W/2, self.game.DISPLAY_H/2 - 80)
            self.game.draw_text("Start Game", 20, self.startx, self.starty)
            self.game.draw_text("Options", 20, self.optionsx, self.optionsy)
            self.game.draw_text("Credits", 20, self.creditsx, self.creditsy)
            self.draw_cursor()
            self.blit_screen()

    def move_cursor(self):
        if self.game.DOWN_KEY:
            if self.state == 'Start':
                self.cursor_rect.midtop = (self.optionsx + self.offset, self.optionsy)
                self.state = 'Options'
            elif self.state == 'Options':
                self.cursor_rect.midtop = (self.creditsx + self.offset, self.creditsy)
                self.state = 'Credits'
            elif self.state == 'Credits':
                self.cursor_rect.midtop = (self.startx + self.offset, self.starty)
                self.state = 'Start'
        elif self.game.UP_KEY:
            if self.state == 'Start':
                self.cursor_rect.midtop = (self.creditsx + self.offset, self.creditsy)
                self.state = 'Credits'
            elif self.state == 'Options':
                self.cursor_rect.midtop = (self.startx + self.offset, self.starty)
                self.state = 'Start'
            elif self.state == 'Credits':
                self.cursor_rect.midtop = (self.optionsx + self.offset, self.optionsy)
                self.state = 'Options'

    def check_input(self):
        self.move_cursor()
        if self.game.START_KEY:
            if self.state == 'Start':
                self.game.playing = True
            elif self.state == 'Options':
                self.game.curr_menu = self.game.options
            elif self.state == 'Credits':
                self.game.curr_menu = self.game.credits
            self.run_display = False

class OptionsMenu(Menu):
    def __init__(self, game):
        Menu.__init__(self, game)
        self.state = "Volume"
        self.volx, self.voly = self.game.DISPLAY_W/2, self.game.DISPLAY_H/2 - 40
        self.backx, self.backy = self.game.DISPLAY_W/2, self.game.DISPLAY_H/2 + 40
        self.cursor_rect.midtop = (self.volx + self.offset, self.voly)

    def display_menu(self):
        self.run_display = True
        while self.run_display:
            self.game.check_events()
            self.check_input()
            self.game.display.fill(self.game.BLACK)
            self.game.draw_text('OPTIONS', 25, self.game.DISPLAY_W/2, self.game.DISPLAY_H/2 - 80)
            self.game.draw_text("Volume", 20, self.volx, self.voly)
            self.game.draw_text("Back", 20, self.backx, self.backy)
            self.draw_cursor()
            self.blit_screen()

    def check_input(self):
        if self.game.BACK_KEY:
            self.game.curr_menu = self.game.main_menu
            self.run_display = False
        elif self.game.START_KEY:
            # 这里可以后续添加音量调整逻辑
            pass
        self.move_cursor()

    def move_cursor(self):
        if self.game.DOWN_KEY:
            if self.state == 'Volume':
                self.cursor_rect.midtop = (self.backx + self.offset, self.backy)
                self.state = 'Back'
            elif self.state == 'Back':
                self.cursor_rect.midtop = (self.volx + self.offset, self.voly)
                self.state = 'Volume'
        elif self.game.UP_KEY:
            if self.state == 'Volume':
                self.cursor_rect.midtop = (self.backx + self.offset, self.backy)
                self.state = 'Back'
            elif self.state == 'Back':
                self.cursor_rect.midtop = (self.volx + self.offset, self.voly)
                self.state = 'Volume'

class CreditsMenu(Menu):
    def __init__(self, game):
        Menu.__init__(self, game)

    def display_menu(self):
        self.run_display = True
        while self.run_display:
            self.game.check_events()
            if self.game.BACK_KEY or self.game.START_KEY:
                self.game.curr_menu = self.game.main_menu
                self.run_display = False
            self.game.display.fill(self.game.BLACK)
            self.game.draw_text('CREDITS', 25, self.game.DISPLAY_W/2, self.game.DISPLAY_H/2 - 80)
            self.game.draw_text('Made with Pygame', 15, self.game.DISPLAY_W/2, self.game.DISPLAY_H/2)
            self.blit_screen()

# 主游戏类
class Game():
    def __init__(self):
        self.running, self.playing = True, False
        self.UP_KEY, self.DOWN_KEY, self.START_KEY, self.BACK_KEY = False, False, False, False
        self.DISPLAY_W, self.DISPLAY_H = 1080, 720  # 统一窗口大小
        self.display = pygame.Surface((self.DISPLAY_W,self.DISPLAY_H))
        self.window = pygame.display.set_mode((self.DISPLAY_W,self.DISPLAY_H))
        pygame.display.set_caption("Lunar Dungeon")
        # 加载图标并增加异常处理
        try:
            icon = pygame.image.load('moon.png')
            pygame.display.set_icon(icon)
        except:
            print("Warning: moon.png not found, using default icon")
        # 字体容错处理
        self.font_name = '8-BIT WONDER.TTF'
        if not pygame.font.match_font(self.font_name.split('.')[0]):
            self.font_name = pygame.font.get_default_font()
        self.BLACK, self.WHITE = (0, 0, 0), (255, 255, 255)
        self.main_menu = MainMenu(self)
        self.options = OptionsMenu(self)
        self.credits = CreditsMenu(self)
        self.curr_menu = self.main_menu

    def game_loop(self):
        while self.playing:
            self.check_events()
            if self.START_KEY:
                self.playing = False
            self.display.fill(self.BLACK)
            self.draw_text('Game Started! Press ENTER to return to menu', 20, self.DISPLAY_W/2, self.DISPLAY_H/2)
            self.window.blit(self.display, (0,0))
            pygame.display.update()
            self.reset_keys()

    def check_events(self):
        for event in pygame.event.get():
            if event.type == pygame.QUIT:
                self.running, self.playing = False, False
                self.curr_menu.run_display = False
            if event.type == pygame.KEYDOWN:
                if event.key == pygame.K_RETURN:
                    self.START_KEY = True
                if event.key == pygame.K_BACKSPACE:
                    self.BACK_KEY = True
                if event.key == pygame.K_DOWN:
                    self.DOWN_KEY = True
                if event.key == pygame.K_UP:
                    self.UP_KEY = True

    def reset_keys(self):
        self.UP_KEY, self.DOWN_KEY, self.START_KEY, self.BACK_KEY = False, False, False, False

    def draw_text(self, text, size, x, y ):
        font = pygame.font.Font(self.font_name,size)
        text_surface = font.render(text, True, self.WHITE)
        text_rect = text_surface.get_rect()
        text_rect.center = (x,y)
        self.display.blit(text_surface,text_rect)

# 启动游戏入口
if __name__ == "__main__":
    lunar_game = Game()
    while lunar_game.running:
        lunar_game.curr_menu.display_menu()
        lunar_game.game_loop()
    pygame.quit()
    sys.exit()

关键修复点说明

  1. 补全菜单类:添加了Menu基类和三个具体菜单类,让菜单逻辑可以正常运行。
  2. 移除冗余初始化:只在代码开头做一次Pygame初始化,避免重复操作。
  3. 统一窗口大小:把Game类的窗口大小改成和初始窗口一致的1080x720,避免窗口切换问题。
  4. 添加启动逻辑:在代码末尾实例化Game类并启动菜单循环,让菜单终于能被执行到。
  5. 增加容错处理:包括字体和图标加载的异常处理,避免程序崩溃。

现在运行代码,你就能看到正常显示的主菜单了,用上下方向键切换选项,回车键确认,退格键返回哦!

内容的提问来源于stack exchange,提问作者user17025844

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.04.30 19:47:30