"""Menu system module for PygStormGames. Handles main menu and submenu functionality for games. """ import os import pyglet from os.path import isfile, join from pyglet.window import key class Menu: """Handles menu systems.""" def __init__(self, game): """Initialize menu system. Args: game (PygStormGames): Reference to main game object """ self.game = game self.currentIndex = 0 def show_menu(self, options, title=None, with_music=False): """Display a menu and return selected option.""" if with_music: try: if self.game.sound.currentBgm: self.game.sound.currentBgm.pause() self.game.sound.play_bgm("sounds/music_menu.ogg") except: pass self.currentIndex = 0 lastSpoken = -1 if title: self.game.speech.speak(title) validKeys = [ pyglet.window.key.ESCAPE, pyglet.window.key.RETURN, pyglet.window.key.UP, pyglet.window.key.DOWN, pyglet.window.key.W, pyglet.window.key.S, pyglet.window.key.HOME, pyglet.window.key.END, pyglet.window.key.PAGEUP, pyglet.window.key.PAGEDOWN, pyglet.window.key.INSERT, pyglet.window.key.DELETE ] while True: # Speak current option if changed if self.currentIndex != lastSpoken: self.game.speech.speak(options[self.currentIndex]) lastSpoken = self.currentIndex key, keyModifiers = self.game.wait(validKeys) # Handle Alt+volume controls if keyModifiers & pyglet.window.key.MOD_ALT: if key == pyglet.window.key.PAGEUP: self.game.sound.adjust_master_volume(0.1) elif key == pyglet.window.key.PAGEDOWN: self.game.sound.adjust_master_volume(-0.1) elif key == pyglet.window.key.HOME: self.game.sound.adjust_bgm_volume(0.1) elif key == pyglet.window.key.END: self.game.sound.adjust_bgm_volume(-0.1) elif key == pyglet.window.key.INSERT: self.game.sound.adjust_sfx_volume(0.1) elif key == pyglet.window.key.DELETE: self.game.sound.adjust_sfx_volume(-0.1) continue if key == pyglet.window.key.ESCAPE: if "exit" in options: # Handle exit cleanup immediately self.game.exit_game() return if key == pyglet.window.key.HOME and self.currentIndex != 0: self.currentIndex = 0 self.game.sound.play_sound('menu-move') lastSpoken = -1 # Force speech elif key == pyglet.window.key.END and self.currentIndex != len(options) - 1: self.currentIndex = len(options) - 1 self.game.sound.play_sound('menu-move') lastSpoken = -1 # Force speech elif key in (pyglet.window.key.DOWN, pyglet.window.key.S) and self.currentIndex < len(options) - 1: self.currentIndex += 1 self.game.sound.play_sound('menu-move') lastSpoken = -1 # Force speech elif key in (pyglet.window.key.UP, pyglet.window.key.W) and self.currentIndex > 0: self.currentIndex -= 1 self.game.sound.play_sound('menu-move') lastSpoken = -1 # Force speech elif key == pyglet.window.key.RETURN: self.game.sound.play_sound('menu-select') return options[self.currentIndex] def game_menu(self): """Show main game menu.""" options = [ "play", "instructions", "learn_sounds", "credits", "donate", "exit" ] while True: selection = self.show_menu(options, with_music=True) if selection == "play": return selection elif selection == "instructions": # Pause menu music self.game.sound.pause_bgm() self.game.display.instructions(self.game.speech) # Resume menu music self.game.sound.resume_bgm() elif selection == "learn_sounds": if self.learn_sounds() == "menu": continue elif selection == "credits": # Pause menu music self.game.sound.pause_bgm() self.game.display.credits(self.game.speech) # Resume menu music self.game.sound.resume_bgm() elif selection == "donate": # Pause menu music self.game.sound.pause_bgm() self.game.display.donate(self.game.speech) # Resume menu music self.game.sound.resume_bgm() elif selection == "exit": self.game.exit_game() def learn_sounds(self): """Interactive menu for learning game sounds. Allows users to: - Navigate through available sounds - Play selected sounds - Return to menu with escape key Returns: str: "menu" if user exits with escape """ try: self.game.sound.currentBgm.pause() except: pass self.currentIndex = 0 # Get list of available sounds, excluding special sounds soundFiles = [f for f in os.listdir("sounds/") if isfile(join("sounds/", f)) and (f.split('.')[1].lower() in ["ogg", "wav"]) and (f.split('.')[0].lower() not in ["game-intro", "music_menu"]) and (not f.lower().startswith("_"))] if not soundFiles: self.game.speech.speak("No sounds available to learn.") return "menu" validKeys = [ pyglet.window.key.ESCAPE, pyglet.window.key.RETURN, pyglet.window.key.UP, pyglet.window.key.DOWN, pyglet.window.key.W, pyglet.window.key.S ] # Speak initial sound name self.game.speech.speak(soundFiles[self.currentIndex][:-4]) while True: key, _ = self.game.wait(validKeys) if key == pyglet.window.key.ESCAPE: try: self.game.sound.currentBgm.play() except: pass return "menu" if key in [pyglet.window.key.DOWN, pyglet.window.key.S]: if self.currentIndex < len(soundFiles) - 1: self.game.sound.stop_all_sounds() self.currentIndex += 1 self.game.speech.speak(soundFiles[self.currentIndex][:-4]) if key in [pyglet.window.key.UP, pyglet.window.key.W]: if self.currentIndex > 0: self.game.sound.stop_all_sounds() self.currentIndex -= 1 self.game.speech.speak(soundFiles[self.currentIndex][:-4]) if key == pyglet.window.key.RETURN: soundName = soundFiles[self.currentIndex][:-4] self.game.sound.stop_all_sounds() self.game.sound.play_sound(soundName)