225 lines
7.6 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
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)