Add settings screen with graphics quality and physics controls
Some checks failed
Build / build (push) Failing after 19s

Created dedicated settings route and screen for game configuration:
- Settings UI with quality level dropdowns for planets, asteroids, and sun
- Physics enable/disable toggle
- Save and reset to defaults functionality
- localStorage persistence with feedback messages

Added settings navigation:
- Blue settings link button in game view header
- Integrated with existing hash-based router
- Back navigation to main menu

Settings features:
- Four texture quality levels: WIREFRAME, SIMPLE_MATERIAL, FULL_TEXTURE, PBR_TEXTURE
- Physics toggle for performance optimization
- Quality level guide with explanations
- Persistent settings across sessions
- Visual feedback on save/reset actions

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
Michael Mainguy 2025-10-30 09:11:56 -05:00
parent 181a427875
commit db970ecc8a
4 changed files with 223 additions and 5 deletions

View File

@ -20,6 +20,7 @@
<div data-view="game"> <div data-view="game">
<canvas id="gameCanvas"></canvas> <canvas id="gameCanvas"></canvas>
<a href="#/editor" class="editor-link">📝 Level Editor</a> <a href="#/editor" class="editor-link">📝 Level Editor</a>
<a href="#/settings" class="settings-link">⚙️ Settings</a>
<div id="mainDiv"> <div id="mainDiv">
<div id="loadingDiv">Loading...</div> <div id="loadingDiv">Loading...</div>
<div id="levelSelect"> <div id="levelSelect">
@ -259,6 +260,118 @@
</div> </div>
</div> </div>
<!-- Settings View -->
<div data-view="settings" style="display: none;">
<div class="editor-container">
<a href="#/" class="back-link">← Back to Game</a>
<h1>⚙️ Game Settings</h1>
<p class="subtitle">Configure graphics quality and physics settings</p>
<div class="settings-grid">
<!-- Graphics Settings -->
<div class="section">
<h2>🎨 Graphics Quality</h2>
<p style="color: #aaa; font-size: 0.9em; margin-bottom: 20px;">
Higher quality settings may impact performance on lower-end devices.
</p>
<div class="form-group">
<label for="planetTextureLevel">Planet Quality</label>
<select id="planetTextureLevel">
<option value="WIREFRAME">Wireframe (Lowest)</option>
<option value="SIMPLE_MATERIAL">Simple Material</option>
<option value="FULL_TEXTURE">Full Texture (Recommended)</option>
<option value="PBR_TEXTURE">PBR Texture (Highest)</option>
</select>
<div class="help-text">Controls planet rendering quality and detail</div>
</div>
<div class="form-group">
<label for="asteroidTextureLevel">Asteroid Quality</label>
<select id="asteroidTextureLevel">
<option value="WIREFRAME">Wireframe (Lowest)</option>
<option value="SIMPLE_MATERIAL">Simple Material</option>
<option value="FULL_TEXTURE">Full Texture (Recommended)</option>
<option value="PBR_TEXTURE">PBR Texture (Highest)</option>
</select>
<div class="help-text">Controls asteroid rendering quality and detail</div>
</div>
<div class="form-group">
<label for="sunTextureLevel">Sun Quality</label>
<select id="sunTextureLevel">
<option value="WIREFRAME">Wireframe (Lowest)</option>
<option value="SIMPLE_MATERIAL">Simple Material</option>
<option value="FULL_TEXTURE">Full Texture (Recommended)</option>
<option value="PBR_TEXTURE">PBR Texture (Highest)</option>
</select>
<div class="help-text">Controls sun rendering quality</div>
</div>
</div>
<!-- Physics Settings -->
<div class="section">
<h2>⚛️ Physics</h2>
<p style="color: #aaa; font-size: 0.9em; margin-bottom: 20px;">
Disabling physics can significantly improve performance but will prevent gameplay.
</p>
<div class="form-group">
<label style="display: flex; align-items: center; cursor: pointer; user-select: none;">
<input type="checkbox" id="physicsEnabled" style="
width: 20px;
height: 20px;
margin-right: 10px;
cursor: pointer;
accent-color: #4CAF50;
">
<span>Enable Physics</span>
</label>
<div class="help-text">
Required for collisions, shooting, and asteroid movement. Disabling this will prevent gameplay but may help with debugging or viewing the scene.
</div>
</div>
</div>
<!-- Info Section -->
<div class="section">
<h2> Quality Level Guide</h2>
<div style="color: #ccc; font-size: 0.9em; line-height: 1.8;">
<p><strong style="color: #4CAF50;">Wireframe:</strong> Minimal rendering, shows mesh structure only. Best for debugging or very low-end devices.</p>
<p><strong style="color: #4CAF50;">Simple Material:</strong> Basic solid colors without textures. Good performance with basic visuals.</p>
<p><strong style="color: #4CAF50;">Full Texture:</strong> Standard textures with procedural generation. Recommended for most users.</p>
<p><strong style="color: #4CAF50;">PBR Texture:</strong> Physically-based rendering with enhanced materials. Best visual quality but higher GPU usage.</p>
</div>
</div>
<!-- Current Config Display -->
<div class="section">
<h2>💾 Storage Info</h2>
<div style="color: #ccc; font-size: 0.9em; line-height: 1.8;">
<p>Settings are automatically saved to your browser's local storage and will persist between sessions.</p>
<p style="color: #FF9800; margin-top: 10px;">
⚠️ Note: Changes will take effect when you start a new level. Restart the current level to see changes.
</p>
</div>
</div>
</div>
<div class="button-group">
<button class="btn-primary" id="saveSettingsBtn">💾 Save Settings</button>
<button class="btn-secondary" id="resetSettingsBtn">🔄 Reset to Defaults</button>
</div>
<div id="settingsMessage" style="
text-align: center;
margin-top: 20px;
font-size: 1.1em;
opacity: 0;
transition: opacity 0.3s;
"></div>
</div>
</div>
<script type="module" src="/src/main.ts"></script> <script type="module" src="/src/main.ts"></script>
</body> </body>
</html> </html>

View File

@ -115,11 +115,10 @@ body {
box-shadow: 0 5px 15px rgba(102, 126, 234, 0.4); box-shadow: 0 5px 15px rgba(102, 126, 234, 0.4);
} }
.editor-link { .editor-link,
.settings-link {
position: absolute; position: absolute;
top: 20px; top: 20px;
right: 20px;
background: rgba(76, 175, 80, 0.8);
color: white; color: white;
padding: 10px 20px; padding: 10px 20px;
border-radius: 5px; border-radius: 5px;
@ -129,13 +128,29 @@ body {
z-index: 2000; z-index: 2000;
} }
.editor-link {
right: 180px;
background: rgba(76, 175, 80, 0.8);
}
.editor-link:hover { .editor-link:hover {
background: rgba(76, 175, 80, 1); background: rgba(76, 175, 80, 1);
transform: scale(1.05); transform: scale(1.05);
} }
.settings-link {
right: 20px;
background: rgba(33, 150, 243, 0.8);
}
.settings-link:hover {
background: rgba(33, 150, 243, 1);
transform: scale(1.05);
}
/* Editor View Styles */ /* Editor View Styles */
[data-view="editor"] { [data-view="editor"],
[data-view="settings"] {
background: linear-gradient(135deg, #0a0618, #1a1033, #0f0c29); background: linear-gradient(135deg, #0a0618, #1a1033, #0f0c29);
min-height: 100vh; min-height: 100vh;
padding: 15px; padding: 15px;
@ -165,7 +180,8 @@ body {
text-shadow: 0 1px 3px rgba(0,0,0,0.8); text-shadow: 0 1px 3px rgba(0,0,0,0.8);
} }
.editor-grid { .editor-grid,
.settings-grid {
display: grid; display: grid;
grid-template-columns: repeat(auto-fit, minmax(min(100%, 320px), 1fr)); grid-template-columns: repeat(auto-fit, minmax(min(100%, 320px), 1fr));
gap: 15px; gap: 15px;

View File

@ -229,6 +229,17 @@ router.on('/editor', () => {
} }
}); });
router.on('/settings', () => {
showView('settings');
// Dynamically import and initialize settings
if (!(window as any).__settingsInitialized) {
import('./settingsScreen').then((module) => {
module.initializeSettingsScreen();
(window as any).__settingsInitialized = true;
});
}
});
// Generate default levels if localStorage is empty // Generate default levels if localStorage is empty
generateDefaultLevels(); generateDefaultLevels();

78
src/settingsScreen.ts Normal file
View File

@ -0,0 +1,78 @@
import { GameConfig, TextureLevel } from "./gameConfig";
/**
* Initialize the settings screen
*/
export function initializeSettingsScreen(): void {
const config = GameConfig.getInstance();
// Get form elements
const planetTextureSelect = document.getElementById('planetTextureLevel') as HTMLSelectElement;
const asteroidTextureSelect = document.getElementById('asteroidTextureLevel') as HTMLSelectElement;
const sunTextureSelect = document.getElementById('sunTextureLevel') as HTMLSelectElement;
const physicsEnabledCheckbox = document.getElementById('physicsEnabled') as HTMLInputElement;
const saveBtn = document.getElementById('saveSettingsBtn');
const resetBtn = document.getElementById('resetSettingsBtn');
const messageDiv = document.getElementById('settingsMessage');
// Load current settings
loadSettings();
// Save button handler
saveBtn?.addEventListener('click', () => {
saveSettings();
showMessage('Settings saved successfully!', 'success');
});
// Reset button handler
resetBtn?.addEventListener('click', () => {
if (confirm('Are you sure you want to reset all settings to defaults?')) {
config.reset();
loadSettings();
showMessage('Settings reset to defaults', 'info');
}
});
/**
* Load current settings into form
*/
function loadSettings(): void {
if (planetTextureSelect) planetTextureSelect.value = config.planetTextureLevel;
if (asteroidTextureSelect) asteroidTextureSelect.value = config.asteroidTextureLevel;
if (sunTextureSelect) sunTextureSelect.value = config.sunTextureLevel;
if (physicsEnabledCheckbox) physicsEnabledCheckbox.checked = config.physicsEnabled;
}
/**
* Save form settings to GameConfig
*/
function saveSettings(): void {
config.planetTextureLevel = planetTextureSelect.value as TextureLevel;
config.asteroidTextureLevel = asteroidTextureSelect.value as TextureLevel;
config.sunTextureLevel = sunTextureSelect.value as TextureLevel;
config.physicsEnabled = physicsEnabledCheckbox.checked;
config.save();
}
/**
* Show a temporary message
*/
function showMessage(message: string, type: 'success' | 'info' | 'warning'): void {
if (!messageDiv) return;
const colors = {
success: '#4CAF50',
info: '#2196F3',
warning: '#FF9800'
};
messageDiv.textContent = message;
messageDiv.style.color = colors[type];
messageDiv.style.opacity = '1';
setTimeout(() => {
messageDiv.style.opacity = '0';
}, 3000);
}
}