Optional timeouts for wait methods. Various bug fixes.

This commit is contained in:
Storm Dragon 2025-02-24 01:59:47 -05:00
parent 6bddf282a7
commit 4d59a610a0
4 changed files with 67 additions and 27 deletions

View File

@ -89,17 +89,20 @@ class pygstormgames:
self.speech.cleanup()
pyglet.app.exit()
def wait(self, validKeys=None):
"""Wait for key press(es).
def wait(self, validKeys=None, timeout=None):
"""Wait for key press(es) with optional timeout.
Args:
validKeys (list, optional): List of pyglet.window.key values to wait for.
If None, accepts any key press.
timeout (float, optional): Time in seconds to wait for input.
If None, waits indefinitely.
Returns:
tuple: (key, modifiers) that were pressed
tuple: (key, modifiers) that were pressed. Returns (None, None) on timeout.
"""
keyResult = [None, None] # Use list to allow modification in closure
start_time = time.time()
def on_key_press(symbol, modifiers):
if validKeys is None or symbol in validKeys:
@ -110,25 +113,31 @@ class pygstormgames:
# Register temporary handler
self.display.window.push_handlers(on_key_press=on_key_press)
# Wait for valid key press
# Wait for valid key press or timeout
while keyResult[0] is None:
self.display.window.dispatch_events()
pyglet.clock.tick()
# Check for timeout
if timeout is not None and time.time() - start_time > timeout:
break
# Clean up
self.display.window.remove_handlers()
return tuple(keyResult)
def wait_for_completion(self, condition, validKeys=None):
"""Wait for either a condition to be met or valid keys to be pressed.
def wait_for_completion(self, condition, validKeys=None, timeout=None):
"""Wait for either a condition to be met, valid keys to be pressed, or timeout.
Args:
condition: Function that returns True when waiting should end
validKeys (list, optional): List of pyglet.window.key values that can interrupt
If None, uses ESCAPE, RETURN, and SPACE
timeout (float, optional): Time in seconds to wait before timing out
If None, waits indefinitely
Returns:
bool: True if interrupted by key press, False if condition was met
bool: True if interrupted by key press or timeout, False if condition was met
"""
if validKeys is None:
validKeys = [pyglet.window.key.ESCAPE,
@ -136,6 +145,7 @@ class pygstormgames:
pyglet.window.key.SPACE]
interrupted = [False] # Use list to allow modification in closure
start_time = time.time()
def on_key_press(symbol, modifiers):
if symbol in validKeys:
@ -148,6 +158,11 @@ class pygstormgames:
self.display.window.dispatch_events()
pyglet.clock.tick()
# Check for timeout
if timeout is not None and time.time() - start_time > timeout:
interrupted[0] = True
break
self.display.window.remove_handlers()
return interrupted[0]

View File

@ -37,6 +37,8 @@ class Display:
text (list): List of text lines to display
speech (Speech): Speech system for audio output
"""
# Stop bgm if present.
self.game.sound.pause_bgm()
# Store original text with blank lines for copying
self.originalText = text.copy()
@ -163,11 +165,20 @@ class Display:
app = wx.App(False)
dialog = wx.TextEntryDialog(None, prompt, "Input", defaultText)
dialog.SetValue(defaultText)
# Bring dialog to front and give it focus
dialog.Raise()
dialog.SetFocus()
if dialog.ShowModal() == wx.ID_OK:
userInput = dialog.GetValue()
else:
userInput = None
dialog.Destroy()
# Return focus to game window
self.window.activate()
return userInput
def donate(self, speech):

View File

@ -3,6 +3,7 @@
Handles high score tracking with player names and score management.
"""
import pyglet
import time
class Scoreboard:
@ -121,6 +122,12 @@ class Scoreboard:
self.game.config.set_value("scoreboard", f"score_{i+1}", str(entry['score']))
self.game.config.set_value("scoreboard", f"name_{i+1}", entry['name'])
# Force window refresh after dialog
self.game.display.window.dispatch_events()
self.game.speech.speak(f"Congratulations {name}! You got position {position} on the scoreboard!")
time.sleep(1)
# Make sure window is still responsive
self.game.display.window.dispatch_events()
return True

View File

@ -237,12 +237,19 @@ class Sound:
if self.currentBgm:
self.currentBgm.pause()
if soundName not in self.sounds:
# Find all matching sound variations
matches = [name for name in self.sounds.keys()
if re.match(f"^{soundName}.*", name)]
if not matches:
return
# Pick a random variation
selected_sound = random.choice(matches)
# Create and configure the player
player = pyglet.media.Player()
player.queue(self.sounds[soundName])
player.queue(self.sounds[selected_sound])
player.volume = self.sfxVolume * self.masterVolume
# Start playback
@ -250,7 +257,7 @@ class Sound:
# Make sure to give pyglet enough cycles to start playing
startTime = time.time()
duration = self.sounds[soundName].duration
duration = self.sounds[selected_sound].duration
pyglet.clock.tick()
# Wait for completion or skip