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