Added the ability to create submenus with instructions.

This commit is contained in:
Storm Dragon
2025-09-07 02:38:27 -04:00
parent ca2d0d34bd
commit dcd204e476
2 changed files with 90 additions and 2 deletions

88
menu.py
View File

@@ -25,6 +25,94 @@ from .display import display_text
from .scoreboard import Scoreboard
from .services import PathService, ConfigService
def instruction_menu(sounds, instruction_text, *options):
"""Display a menu with an instruction announcement at the top.
The instruction text is announced as item 0 but is not selectable.
The actual menu items start at index 1, and navigation skips the instruction.
Args:
sounds (dict): Dictionary of sound objects
instruction_text (str): The instruction/context text to announce
*options: Menu options to display
Returns:
str: Selected menu option or None if cancelled
"""
# Get speech instance
speech = Speech.get_instance()
# Create combined list with instruction at index 0
all_items = [instruction_text] + list(options)
loop = True
pygame.mixer.stop()
current_index = 0 # Start at instruction
last_spoken = -1
# Clear any pending events
pygame.event.clear()
while loop:
if current_index != last_spoken:
speech.speak(all_items[current_index])
last_spoken = current_index
event = pygame.event.wait()
if event.type == pygame.KEYDOWN:
if event.key == pygame.K_ESCAPE:
return None
elif event.key in [pygame.K_DOWN, pygame.K_s]:
moved = False
if current_index == 0: # On instruction, go to first menu item
current_index = 1
moved = True
elif current_index < len(all_items) - 1: # Normal navigation
current_index += 1
moved = True
if moved:
try:
sounds['menu-move'].play()
except:
pass
elif event.key in [pygame.K_UP, pygame.K_w]:
if current_index > 1: # Can move up from menu items (but not to instruction)
current_index -= 1
try:
sounds['menu-move'].play()
except:
pass
elif event.key == pygame.K_HOME:
target_index = 1 if current_index != 1 else current_index # Go to first menu item
if target_index != current_index:
current_index = target_index
try:
sounds['menu-move'].play()
except:
pass
elif event.key == pygame.K_END and current_index != len(all_items) - 1:
current_index = len(all_items) - 1
try:
sounds['menu-move'].play()
except:
pass
elif event.key == pygame.K_RETURN:
if current_index == 0: # Can't select the instruction
continue
try:
sounds['menu-select'].play()
time.sleep(sounds['menu-select'].get_length())
except:
pass
return options[current_index - 1] # Adjust for instruction offset
elif event.type == pygame.QUIT:
return None
pygame.event.pump()
pygame.event.clear()
time.sleep(0.001)
def game_menu(sounds, playCallback=None, *customOptions):
"""Display and handle the main game menu with standard and custom options.