pygstormgames/menu.py
2025-03-11 21:08:02 -04:00

233 lines
8.0 KiB
Python

"""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
# Get list of available sounds, excluding music and ambiance directories
soundList = self.game.sound.get_sound_list()
if not soundList:
self.game.speech.speak("No sounds available to learn.")
return "menu"
# Sort sounds by name
soundList.sort()
self.currentIndex = 0
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 instructions
self.game.speech.speak("Learn game sounds. Use up and down arrow keys or W/S to navigate, Enter to play sound, Escape to exit.")
# Speak initial sound name
soundName = soundList[self.currentIndex]
displayName = soundName.replace("/", " in folder ")
self.game.speech.speak(f"{displayName}: 1 of {len(soundList)}")
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(soundList) - 1:
self.game.sound.stop_all_sounds()
self.currentIndex += 1
soundName = soundList[self.currentIndex]
displayName = soundName.replace("/", " in folder ")
self.game.speech.speak(f"{displayName}: {self.currentIndex + 1} of {len(soundList)}")
if key in [pyglet.window.key.UP, pyglet.window.key.W]:
if self.currentIndex > 0:
self.game.sound.stop_all_sounds()
self.currentIndex -= 1
soundName = soundList[self.currentIndex]
displayName = soundName.replace("/", " in folder ")
self.game.speech.speak(f"{displayName}: {self.currentIndex + 1} of {len(soundList)}")
if key == pyglet.window.key.RETURN:
soundName = soundList[self.currentIndex]
self.game.sound.stop_all_sounds()
self.game.sound.play_sound(soundName)