Fix infinite recursion bug and remove old Quick Play implementation
- Fixed infinite recursion in loadMainTask() using setTimeout to break call stack - Removed old in-window Quick Play mode from gameModeManager - Removed Quick Play UI configuration from index.html - Cleaned up Quick Play specific code from game.js - Quick Play now uses dedicated quick-play.html file only (newer version) - Fixed syntax errors from code removal
This commit is contained in:
parent
c33b0211d6
commit
6701a8e7bf
129
src/core/game.js
129
src/core/game.js
|
|
@ -2193,26 +2193,6 @@ class TaskChallengeGame {
|
|||
});
|
||||
});
|
||||
|
||||
// Add listeners for Quick Play controls
|
||||
const playTimeSelect = document.getElementById('play-time-select');
|
||||
if (playTimeSelect) {
|
||||
console.log('⏱️ Found play time select, adding listener');
|
||||
playTimeSelect.addEventListener('change', () => {
|
||||
console.log('⏱️ Play time select changed');
|
||||
this.handleQuickPlayTimeChange();
|
||||
});
|
||||
} else {
|
||||
console.log('⚠️ Play time select not found');
|
||||
}
|
||||
|
||||
// Add listeners for custom input changes (if elements exist)
|
||||
const customPlayTimeValue = document.getElementById('custom-play-time-value');
|
||||
if (customPlayTimeValue) {
|
||||
customPlayTimeValue.addEventListener('input', () => {
|
||||
this.handleCustomPlayTimeChange();
|
||||
});
|
||||
}
|
||||
|
||||
// Initialize with default mode
|
||||
this.handleGameModeChange();
|
||||
}
|
||||
|
|
@ -2226,19 +2206,9 @@ class TaskChallengeGame {
|
|||
console.log(`🎮 Game mode changed to: ${selectedMode}`);
|
||||
|
||||
// Show/hide configuration options based on selected mode (if elements exist)
|
||||
const quickPlayConfig = document.getElementById('quick-play-config');
|
||||
|
||||
// Hide all configs first (in case there are any old ones)
|
||||
const allConfigs = document.querySelectorAll('.mode-config');
|
||||
allConfigs.forEach(config => config.style.display = 'none');
|
||||
|
||||
// Show Quick Play config (it's the only mode now)
|
||||
if (selectedMode === 'quick-play' && quickPlayConfig) {
|
||||
quickPlayConfig.style.display = 'block';
|
||||
console.log('⚡ Showing Quick Play configuration options');
|
||||
this.handleQuickPlayTimeChange();
|
||||
}
|
||||
|
||||
console.log(`Game state updated:`, {
|
||||
gameMode: this.gameState.gameMode,
|
||||
timeLimit: this.gameState.timeLimit
|
||||
|
|
@ -2319,43 +2289,6 @@ class TaskChallengeGame {
|
|||
}
|
||||
}
|
||||
|
||||
handleQuickPlayTimeChange() {
|
||||
const playTimeSelect = document.getElementById('play-time-select');
|
||||
const customPlayTimeInput = document.getElementById('custom-play-time-input');
|
||||
|
||||
if (!playTimeSelect) {
|
||||
console.log('⚠️ Play time select element not found');
|
||||
return;
|
||||
}
|
||||
|
||||
const selectedValue = playTimeSelect.value;
|
||||
console.log(`⚡ Play time selection: ${selectedValue}`);
|
||||
|
||||
if (customPlayTimeInput) {
|
||||
if (selectedValue === 'custom') {
|
||||
customPlayTimeInput.style.display = 'block';
|
||||
console.log('⚡ Showing custom play time input');
|
||||
this.handleCustomPlayTimeChange();
|
||||
} else {
|
||||
customPlayTimeInput.style.display = 'none';
|
||||
this.gameState.timeLimit = parseInt(selectedValue);
|
||||
console.log(`⚡ Play time set to: ${this.gameState.timeLimit} seconds`);
|
||||
}
|
||||
} else if (selectedValue !== 'custom') {
|
||||
this.gameState.timeLimit = parseInt(selectedValue);
|
||||
console.log(`⚡ Play time set to: ${this.gameState.timeLimit} seconds`);
|
||||
}
|
||||
}
|
||||
|
||||
handleCustomPlayTimeChange() {
|
||||
const customPlayTimeValue = document.getElementById('custom-play-time-value');
|
||||
if (customPlayTimeValue) {
|
||||
const minutes = parseInt(customPlayTimeValue.value) || 15;
|
||||
this.gameState.timeLimit = minutes * 60; // Convert minutes to seconds
|
||||
console.log(`Custom play time set to ${minutes} minutes (${this.gameState.timeLimit} seconds)`);
|
||||
}
|
||||
}
|
||||
|
||||
// XP Calculation Methods
|
||||
calculateTimeBasedXp() {
|
||||
if (!this.gameState.sessionStartTime) return 0;
|
||||
|
|
@ -4727,64 +4660,11 @@ ${usagePercent > 85 ? '⚠️ Storage getting full - consider deleting some imag
|
|||
}
|
||||
|
||||
// Get selected game mode
|
||||
const selectedMode = document.querySelector('input[name="gameMode"]:checked')?.value || 'quick-play';
|
||||
const selectedMode = document.querySelector('input[name="gameMode"]:checked')?.value || 'standard';
|
||||
if (window.gameModeManager) {
|
||||
window.gameModeManager.currentMode = selectedMode;
|
||||
// Map the new mode names to the original game engine modes
|
||||
this.gameState.gameMode = window.gameModeManager.getGameModeForEngine();
|
||||
|
||||
// Apply Quick Play settings
|
||||
if (selectedMode === 'quick-play' && window.quickPlaySettings) {
|
||||
// Set play time
|
||||
this.gameState.timeLimit = window.quickPlaySettings.getPlayTime();
|
||||
console.log(`⚡ Quick Play time limit set to: ${this.gameState.timeLimit} seconds`);
|
||||
|
||||
// Configure background audio
|
||||
const backgroundAudioEnabled = window.quickPlaySettings.isBackgroundAudioEnabled();
|
||||
if (this.audioManager) {
|
||||
if (backgroundAudioEnabled) {
|
||||
this.audioManager.resumePlaylist();
|
||||
console.log('🎵 Background audio enabled for Quick Play');
|
||||
} else {
|
||||
this.audioManager.pausePlaylist();
|
||||
console.log('🔇 Background audio disabled for Quick Play');
|
||||
}
|
||||
}
|
||||
|
||||
// Configure popup images
|
||||
if (this.popupImageManager) {
|
||||
const popupFrequency = window.quickPlaySettings.getPopupFrequency();
|
||||
const popupDuration = window.quickPlaySettings.getPopupDuration();
|
||||
|
||||
// Update popup image settings using the correct method
|
||||
this.popupImageManager.updateConfig({
|
||||
displayDuration: popupDuration * 1000, // Convert to milliseconds
|
||||
});
|
||||
|
||||
// Update periodic popup settings
|
||||
if (this.popupImageManager.updatePeriodicSettings) {
|
||||
this.popupImageManager.updatePeriodicSettings({
|
||||
minInterval: popupFrequency,
|
||||
maxInterval: popupFrequency,
|
||||
displayDuration: popupDuration
|
||||
});
|
||||
}
|
||||
console.log(`🖼️ Popup images: ${popupFrequency}s frequency, ${popupDuration}s duration`);
|
||||
}
|
||||
|
||||
// Configure flash messages
|
||||
if (this.flashMessageManager) {
|
||||
const messageFrequency = window.quickPlaySettings.getMessageFrequency();
|
||||
const messageDuration = window.quickPlaySettings.getMessageDuration();
|
||||
|
||||
// Update flash message settings
|
||||
this.flashMessageManager.updateConfig({
|
||||
displayDuration: messageDuration * 1000, // Convert to milliseconds
|
||||
intervalDelay: messageFrequency * 1000 // Convert to milliseconds
|
||||
});
|
||||
console.log(`💬 Flash messages: ${messageFrequency}s frequency, ${messageDuration}s duration`);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
// Fallback if gameModeManager is not available
|
||||
this.gameState.gameMode = selectedMode === 'timed' ? 'timed' :
|
||||
|
|
@ -4885,8 +4765,8 @@ ${usagePercent > 85 ? '⚠️ Storage getting full - consider deleting some imag
|
|||
// In timed and xp-target modes, reset used tasks and continue
|
||||
console.log(`All tasks completed in ${this.gameState.gameMode} mode, cycling through tasks again`);
|
||||
this.gameState.usedMainTasks = [];
|
||||
// Recursively call loadMainTask to select from reset pool
|
||||
this.loadMainTask();
|
||||
// Use setTimeout to break the recursion chain and prevent stack overflow
|
||||
setTimeout(() => this.loadMainTask(), 0);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
|
@ -4903,7 +4783,8 @@ ${usagePercent > 85 ? '⚠️ Storage getting full - consider deleting some imag
|
|||
} else {
|
||||
console.log(`All tasks completed in ${this.gameState.gameMode} mode, cycling through tasks again`);
|
||||
this.gameState.usedMainTasks = [];
|
||||
this.loadMainTask();
|
||||
// Use setTimeout to break the recursion chain and prevent stack overflow
|
||||
setTimeout(() => this.loadMainTask(), 0);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -5,13 +5,8 @@
|
|||
|
||||
class GameModeManager {
|
||||
constructor() {
|
||||
this.currentMode = 'quick-play'; // Default to quick play mode
|
||||
this.currentMode = 'standard'; // Default to standard mode
|
||||
this.availableModes = {
|
||||
'quick-play': {
|
||||
name: 'Quick Play',
|
||||
description: 'Timed challenge mode with customizable options',
|
||||
icon: '⚡'
|
||||
},
|
||||
'photography-studio': {
|
||||
name: 'Photography Studio',
|
||||
description: 'Dedicated webcam photography and dressing sessions',
|
||||
|
|
@ -87,82 +82,18 @@ class GameModeManager {
|
|||
<h3>Choose Your Game Mode</h3>
|
||||
<div class="game-mode-grid">
|
||||
${Object.entries(this.availableModes).map(([key, mode]) => `
|
||||
<div class="game-mode-card ${key === 'quick-play' ? 'selected' : ''}" data-mode="${key}">
|
||||
<div class="game-mode-card ${key === 'standard' ? 'selected' : ''}" data-mode="${key}">
|
||||
<div class="mode-icon">${mode.icon}</div>
|
||||
<div class="mode-info">
|
||||
<h4>${mode.name}</h4>
|
||||
<h3>${mode.name}</h3>
|
||||
<p>${mode.description}</p>
|
||||
</div>
|
||||
<input type="radio" name="gameMode" value="${key}" id="mode-${key}" ${key === 'quick-play' ? 'checked' : ''}>
|
||||
<input type="radio" name="gameMode" value="${key}" id="mode-${key}" ${key === 'standard' ? 'checked' : ''}>
|
||||
</div>
|
||||
`).join('')}
|
||||
</div>
|
||||
|
||||
<div class="mode-options" id="mode-options">
|
||||
<!-- Quick Play Configuration -->
|
||||
<div class="mode-config" id="quick-play-config" style="display: block;">
|
||||
<div class="config-section">
|
||||
<h4>⚡ Quick Play Options</h4>
|
||||
|
||||
<!-- Play Time Configuration -->
|
||||
<div class="option-group">
|
||||
<label>⏱️ Play Time:
|
||||
<select id="play-time-select">
|
||||
<option value="300">5 minutes</option>
|
||||
<option value="600">10 minutes</option>
|
||||
<option value="900">15 minutes</option>
|
||||
<option value="1200">20 minutes</option>
|
||||
<option value="1800">30 minutes</option>
|
||||
<option value="custom">Custom...</option>
|
||||
</select>
|
||||
</label>
|
||||
<div id="custom-play-time-input" style="display: none; margin-top: 10px;">
|
||||
<label>Custom time (minutes):
|
||||
<input type="number" id="custom-play-time-value" min="1" max="180" value="15" style="width: 60px;">
|
||||
</label>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Background Audio Configuration -->
|
||||
<div class="option-group">
|
||||
<label class="checkbox-label">
|
||||
<input type="checkbox" id="enable-background-audio" checked>
|
||||
🎵 Enable Background Audio Tracks
|
||||
</label>
|
||||
</div>
|
||||
|
||||
<!-- Popup Image Configuration -->
|
||||
<div class="option-group">
|
||||
<h5>🖼️ Popup Images</h5>
|
||||
<div class="sub-option">
|
||||
<label>Frequency (seconds between popups):
|
||||
<input type="number" id="popup-frequency" min="10" max="300" value="60" style="width: 70px;">
|
||||
</label>
|
||||
</div>
|
||||
<div class="sub-option">
|
||||
<label>Duration (seconds displayed):
|
||||
<input type="number" id="popup-duration" min="2" max="30" value="8" style="width: 70px;">
|
||||
</label>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Flash Message Configuration -->
|
||||
<div class="option-group">
|
||||
<h5>💬 Flash Messages</h5>
|
||||
<div class="sub-option">
|
||||
<label>Frequency (seconds between messages):
|
||||
<input type="number" id="message-frequency" min="5" max="300" value="45" style="width: 70px;">
|
||||
</label>
|
||||
</div>
|
||||
<div class="sub-option">
|
||||
<label>Duration (seconds displayed):
|
||||
<input type="number" id="message-duration" min="1" max="10" value="3" style="width: 70px;">
|
||||
</label>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Scenario Configuration -->
|
||||
<div class="mode-config" id="scenario-config" style="display: none;">
|
||||
<div class="config-section">
|
||||
|
|
@ -182,7 +113,7 @@ class GameModeManager {
|
|||
`;
|
||||
|
||||
// Add event listeners for the new controls
|
||||
this.setupQuickPlayListeners();
|
||||
this.bindEvents();
|
||||
|
||||
// Verify the radio buttons were created
|
||||
const radioButtons = gameModeSelection.querySelectorAll('input[name="gameMode"]');
|
||||
|
|
@ -192,59 +123,6 @@ class GameModeManager {
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Setup event listeners for Quick Play configuration
|
||||
*/
|
||||
setupQuickPlayListeners() {
|
||||
// Play time selection
|
||||
const playTimeSelect = document.getElementById('play-time-select');
|
||||
const customPlayTimeInput = document.getElementById('custom-play-time-input');
|
||||
const customPlayTimeValue = document.getElementById('custom-play-time-value');
|
||||
|
||||
if (playTimeSelect) {
|
||||
playTimeSelect.addEventListener('change', () => {
|
||||
if (playTimeSelect.value === 'custom') {
|
||||
customPlayTimeInput.style.display = 'block';
|
||||
} else {
|
||||
customPlayTimeInput.style.display = 'none';
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
// Store all settings in a global object for easy access
|
||||
window.quickPlaySettings = {
|
||||
getPlayTime: () => {
|
||||
const select = document.getElementById('play-time-select');
|
||||
if (select.value === 'custom') {
|
||||
const customValue = document.getElementById('custom-play-time-value');
|
||||
return parseInt(customValue.value) * 60; // Convert minutes to seconds
|
||||
} else {
|
||||
return parseInt(select.value); // Already in seconds
|
||||
}
|
||||
},
|
||||
isBackgroundAudioEnabled: () => {
|
||||
const checkbox = document.getElementById('enable-background-audio');
|
||||
return checkbox ? checkbox.checked : true;
|
||||
},
|
||||
getPopupFrequency: () => {
|
||||
const input = document.getElementById('popup-frequency');
|
||||
return input ? parseInt(input.value) : 60;
|
||||
},
|
||||
getPopupDuration: () => {
|
||||
const input = document.getElementById('popup-duration');
|
||||
return input ? parseInt(input.value) : 8;
|
||||
},
|
||||
getMessageFrequency: () => {
|
||||
const input = document.getElementById('message-frequency');
|
||||
return input ? parseInt(input.value) : 45;
|
||||
},
|
||||
getMessageDuration: () => {
|
||||
const input = document.getElementById('message-duration');
|
||||
return input ? parseInt(input.value) : 3;
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* Remove hint buttons from scenarios in game.js
|
||||
*/
|
||||
|
|
@ -317,20 +195,11 @@ class GameModeManager {
|
|||
const allConfigs = document.querySelectorAll('.mode-config');
|
||||
allConfigs.forEach(config => config.style.display = 'none');
|
||||
|
||||
// Show appropriate config based on mode
|
||||
if (mode === 'quick-play') {
|
||||
const quickPlayConfig = document.getElementById('quick-play-config');
|
||||
if (quickPlayConfig) {
|
||||
quickPlayConfig.style.display = 'block';
|
||||
console.log('⚡ Showing Quick Play configuration');
|
||||
}
|
||||
} else {
|
||||
// Show scenario config for scenario modes
|
||||
const scenarioConfig = document.getElementById('scenario-config');
|
||||
if (scenarioConfig) {
|
||||
scenarioConfig.style.display = 'block';
|
||||
console.log('🎮 Showing scenario configuration');
|
||||
}
|
||||
// Show scenario config for scenario modes
|
||||
const scenarioConfig = document.getElementById('scenario-config');
|
||||
if (scenarioConfig) {
|
||||
scenarioConfig.style.display = 'block';
|
||||
console.log('🎮 Showing scenario configuration');
|
||||
}
|
||||
|
||||
// Update UI to highlight selected mode
|
||||
|
|
@ -344,7 +213,7 @@ class GameModeManager {
|
|||
* Get tasks for the current game mode
|
||||
*/
|
||||
getTasksForMode() {
|
||||
if (this.currentMode === 'standard' || this.currentMode === 'timed' || this.currentMode === 'scored' || this.currentMode === 'quick-play') {
|
||||
if (this.currentMode === 'standard' || this.currentMode === 'timed' || this.currentMode === 'scored') {
|
||||
return this.getStandardTasks();
|
||||
} else {
|
||||
return this.getScenarioModeTasks();
|
||||
|
|
@ -695,7 +564,7 @@ class GameModeManager {
|
|||
* Check if current mode is scenario-based
|
||||
*/
|
||||
isScenarioMode() {
|
||||
return this.currentMode && this.currentMode !== 'standard' && this.currentMode !== 'quick-play';
|
||||
return this.currentMode && this.currentMode !== 'standard';
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
|||
|
|
@ -6,9 +6,7 @@ const gameData = {
|
|||
// Consequence tasks - now sourced from mainGameData.js via GameDataManager
|
||||
consequenceTasks: [],
|
||||
|
||||
// Image directory configuration
|
||||
taskImageDirectory: "images/tasks/",
|
||||
consequenceImageDirectory: "images/consequences/",
|
||||
// Image configuration
|
||||
supportedImageFormats: ['.jpg', '.jpeg', '.png', '.gif'],
|
||||
discoveredTaskImages: [], // Will be populated automatically
|
||||
discoveredConsequenceImages: [], // Will be populated automatically
|
||||
|
|
|
|||
Loading…
Reference in New Issue