This commit is contained in:
cpu
2025-03-29 03:45:26 +01:00
parent 5763407edc
commit 832f19235f
31 changed files with 373 additions and 139 deletions

View File

@@ -7,18 +7,23 @@ let timerInterval = null;
let onTimerTickCallback = null; // Callback for UI updates
let onPlayerSwitchCallback = null; // Callback for when player switches due to time running out
let onGameOverCallback = null; // Callback for when all players run out of time
let timeExpiredFlagsById = new Map(); // Track which players have had their timeout sound played
export function initTimer(options) {
onTimerTickCallback = options.onTimerTick;
onPlayerSwitchCallback = options.onPlayerSwitch;
onGameOverCallback = options.onGameOver;
timeExpiredFlagsById.clear(); // Reset flags on init
}
export function startTimer() {
if (timerInterval) clearInterval(timerInterval); // Clear existing interval if any
// Stop any previous sounds (like low time warning) before starting fresh
audioManager.stopAllSounds(); // Consider if this is too aggressive
audioManager.stopAllSounds();
// Reset the expired sound flags when starting a new timer
timeExpiredFlagsById.clear();
timerInterval = setInterval(() => {
const currentPlayerIndex = state.getCurrentPlayerIndex();
@@ -35,31 +40,23 @@ export function startTimer() {
const newTime = currentPlayer.remainingTime - 1;
state.updatePlayerTime(currentPlayerIndex, newTime); // Update state
// Play timer sounds
// Play timer sounds - ensure we're not leaking audio resources
audioManager.playTimerSound(newTime);
// Notify UI to update
if (onTimerTickCallback) onTimerTickCallback();
} else { // Current player's time just hit 0 or was already 0
// Ensure time is exactly 0 if it somehow went negative (unlikely with check above)
if(currentPlayer.remainingTime < 0) {
// Ensure time is exactly 0 if it somehow went negative
if(currentPlayer.remainingTime < 0) {
state.updatePlayerTime(currentPlayerIndex, 0);
}
// Stop this player's timer tick sound if it was playing
// audioManager.stop('timerTick'); // Or specific low time sound
// Play time expired sound (only once)
// Check if we just hit zero to avoid playing repeatedly
// This logic might be complex, audioManager could handle idempotency
if (currentPlayer.remainingTime === 0 && !currentPlayer.timeExpiredSoundPlayed) {
audioManager.playTimerExpired();
// We need a way to mark that the sound played for this player this turn.
// This might require adding a temporary flag to the player state,
// or handling it within the audioManager. Let's assume audioManager handles it for now.
}
// Play time expired sound (only once per player per game)
if (!timeExpiredFlagsById.has(currentPlayer.id)) {
audioManager.playTimerExpired();
timeExpiredFlagsById.set(currentPlayer.id, true);
}
// Check if the game should end or switch player
if (state.areAllTimersFinished()) {
@@ -69,10 +66,11 @@ export function startTimer() {
// Find the *next* player who still has time
const nextPlayerIndex = state.findNextPlayerWithTime(); // This finds ANY player with time
if (nextPlayerIndex !== -1 && nextPlayerIndex !== currentPlayerIndex) {
// Switch player
// Switch player and ensure we stop any sounds from current player
audioManager.stopTimerSounds(); // Stop specific timer sounds before switching
if (onPlayerSwitchCallback) onPlayerSwitchCallback(nextPlayerIndex);
// Play switch sound (might be handled in app.js based on state change)
// audioManager.play('playerSwitch'); // Or let app.js handle sounds based on actions
// Immediately update UI after switch
if (onTimerTickCallback) onTimerTickCallback();
} else if (nextPlayerIndex === -1) {
@@ -81,7 +79,7 @@ export function startTimer() {
stopTimer(); // Stop timer if state is inconsistent
if (onGameOverCallback) onGameOverCallback(); // Treat as game over
}
// If nextPlayerIndex is the same as currentPlayerIndex, means others are out of time, let this timer continue (or rather, stop ticking down as remainingTime is 0)
// If nextPlayerIndex is the same as currentPlayerIndex, means others are out of time, let this timer continue
}
}
}, 1000);
@@ -90,10 +88,17 @@ export function startTimer() {
export function stopTimer() {
clearInterval(timerInterval);
timerInterval = null;
// Optionally stop timer sounds here if needed
// audioManager.stop('timerTick');
// Stop all timer-related sounds to prevent them from continuing to play
audioManager.stopTimerSounds();
}
export function isTimerRunning() {
return timerInterval !== null;
}
// Clean up resources when the application is closing or component unmounts
export function cleanup() {
stopTimer();
timeExpiredFlagsById.clear();
audioManager.stopAllSounds();
}