177 lines
6.2 KiB
Python
177 lines
6.2 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
|
|
selection = None # Add this to store the selection
|
|
|
|
if title:
|
|
self.game.speech.speak(title)
|
|
|
|
def key_handler(symbol, modifiers): # Define handler outside event
|
|
nonlocal selection, lastSpoken
|
|
# Handle Alt+volume controls
|
|
if modifiers & key.MOD_ALT:
|
|
if symbol == key.PAGEUP:
|
|
self.game.sound.adjust_master_volume(0.1)
|
|
elif symbol == key.PAGEDOWN:
|
|
self.game.sound.adjust_master_volume(-0.1)
|
|
elif symbol == key.HOME:
|
|
self.game.sound.adjust_bgm_volume(0.1)
|
|
elif symbol == key.END:
|
|
self.game.sound.adjust_bgm_volume(-0.1)
|
|
elif symbol == key.INSERT:
|
|
self.game.sound.adjust_sfx_volume(0.1)
|
|
elif symbol == key.DELETE:
|
|
self.game.sound.adjust_sfx_volume(-0.1)
|
|
return
|
|
|
|
if symbol == key.ESCAPE:
|
|
selection = "exit"
|
|
return pyglet.event.EVENT_HANDLED
|
|
|
|
if symbol == key.HOME and self.currentIndex != 0:
|
|
self.currentIndex = 0
|
|
self.game.sound.play_sound('menu-move')
|
|
lastSpoken = -1 # Force speech
|
|
|
|
elif symbol == 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 symbol in (key.DOWN, key.S) and self.currentIndex < len(options) - 1:
|
|
self.currentIndex += 1
|
|
self.game.sound.play_sound('menu-move')
|
|
lastSpoken = -1 # Force speech
|
|
|
|
elif symbol in (key.UP, key.W) and self.currentIndex > 0:
|
|
self.currentIndex -= 1
|
|
self.game.sound.play_sound('menu-move')
|
|
lastSpoken = -1 # Force speech
|
|
|
|
elif symbol == key.RETURN:
|
|
self.game.sound.play_sound('menu-select')
|
|
selection = options[self.currentIndex]
|
|
return pyglet.event.EVENT_HANDLED
|
|
|
|
return pyglet.event.EVENT_HANDLED
|
|
|
|
# Register the handler
|
|
self.game.display.window.push_handlers(on_key_press=key_handler)
|
|
|
|
# Main menu loop
|
|
while selection is None:
|
|
if self.currentIndex != lastSpoken:
|
|
self.game.speech.speak(options[self.currentIndex])
|
|
lastSpoken = self.currentIndex
|
|
self.game.display.window.dispatch_events()
|
|
|
|
# Clean up
|
|
self.game.display.window.remove_handlers()
|
|
return selection
|
|
|
|
def game_menu(self):
|
|
"""Show main game menu."""
|
|
options = [
|
|
"play",
|
|
"instructions",
|
|
"learn_sounds",
|
|
"credits",
|
|
"donate",
|
|
"exit"
|
|
]
|
|
|
|
return self.show_menu(options, with_music=True)
|
|
|
|
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("_"))]
|
|
|
|
# Track last spoken index to avoid repetition
|
|
lastSpoken = -1
|
|
|
|
while True:
|
|
if self.currentIndex != lastSpoken:
|
|
self.game.speech.speak(soundFiles[self.currentIndex][:-4])
|
|
lastSpoken = self.currentIndex
|
|
|
|
event = self.game.display.window.dispatch_events()
|
|
|
|
@self.game.display.window.event
|
|
def on_key_press(symbol, modifiers):
|
|
if symbol == key.ESCAPE:
|
|
try:
|
|
self.game.sound.currentBgm.unpause()
|
|
except:
|
|
pass
|
|
self.game.display.window.remove_handler('on_key_press', on_key_press)
|
|
return "menu"
|
|
|
|
if symbol in [key.DOWN, key.S] and self.currentIndex < len(soundFiles) - 1:
|
|
self.game.sound.stop_all_sounds()
|
|
self.currentIndex += 1
|
|
|
|
if symbol in [key.UP, key.W] and self.currentIndex > 0:
|
|
self.game.sound.stop_all_sounds()
|
|
self.currentIndex -= 1
|
|
|
|
if symbol == key.RETURN:
|
|
try:
|
|
soundName = soundFiles[self.currentIndex][:-4]
|
|
self.game.sound.stop_all_sounds()
|
|
self.game.sound.play_sound(soundName)
|
|
except:
|
|
lastSpoken = -1
|
|
self.game.speech.speak("Could not play sound.")
|