From 9a0eda6bb87726b0113a6053b3c4fcecd6511924 Mon Sep 17 00:00:00 2001 From: Hijau-dev Date: Tue, 16 Dec 2025 08:31:21 +0700 Subject: [PATCH] Update Lobby --- Main.html | 66 +++++++- Script.js | 340 +++++++++++++++++++++++++++++++++++++++ Style.css | 472 +++++++++++++++++++++++++++++++++++++++++++----------- 3 files changed, 780 insertions(+), 98 deletions(-) diff --git a/Main.html b/Main.html index f0cfc34..3a61d54 100644 --- a/Main.html +++ b/Main.html @@ -6,11 +6,73 @@ Space Game - + -
+ + + + + + + + diff --git a/Script.js b/Script.js index 8ba69e0..338ead0 100644 --- a/Script.js +++ b/Script.js @@ -1533,3 +1533,343 @@ function crossfadeToGameOver() { } }, 1000 / 30); } + +// === GAME SETTINGS === +const gameSettings = { + musicEnabled: true, + sfxEnabled: true +}; + +// === DOM ELEMENTS === +const mainMenu = document.getElementById('mainMenu'); +const optionsMenu = document.getElementById('optionsMenu'); +const gameContainer = document.getElementById('gameContainer'); + +const startBtn = document.getElementById('startBtn'); +const optionBtn = document.getElementById('optionBtn'); +const exitBtn = document.getElementById('exitBtn'); +const backBtn = document.getElementById('backBtn'); + +// Toggle Buttons +const musicBtns = document.querySelectorAll('[data-music]'); +const sfxBtns = document.querySelectorAll('[data-sfx]'); + +// === MENU SOUNDS === +const menuHoverSound = new Audio(); +menuHoverSound.src = 'data:audio/wav;base64,UklGRiQAAABXQVZFZm10IBAAAAABAAEAQB8AAEAfAAABAAgAZGF0YQAAAAA='; +const menuClickSound = new Audio(); +menuClickSound.src = 'data:audio/wav;base64,UklGRiQAAABXQVZFZm10IBAAAAABAAEAQB8AAEAfAAABAAgAZGF0YQAAAAA='; + +// === PREVENT DEFAULT GAME START === +window.addEventListener('DOMContentLoaded', () => { + gameStarted = false; +}); + +// === START BUTTON === +startBtn.addEventListener('click', () => { + playSound(menuClickSound); + + // Apply settings to game + applySettings(); + + // Hide menu, show game + mainMenu.style.display = 'none'; + gameContainer.style.display = 'block'; + + // Start the game + if (!gameStarted) { + init(); + } +}); + +// === OPTION BUTTON === +optionBtn.addEventListener('click', () => { + playSound(menuClickSound); + mainMenu.style.display = 'none'; + optionsMenu.style.display = 'flex'; +}); + +// === EXIT BUTTON === +exitBtn.addEventListener('click', () => { + playSound(menuClickSound); + + // Create exit confirmation + const confirmExit = document.createElement('div'); + confirmExit.style.cssText = ` + position: fixed; + top: 50%; + left: 50%; + transform: translate(-50%, -50%); + background: rgba(0, 0, 0, 0.9); + border: 3px solid #00eaff; + border-radius: 20px; + padding: 50px 60px; + z-index: 1000; + text-align: center; + box-shadow: 0 0 40px rgba(0, 234, 255, 0.6); + backdrop-filter: blur(10px); + `; + + confirmExit.innerHTML = ` +

+ EXIT GAME? +

+

+ Are you sure you want to leave? +

+
+ + +
+ `; + + document.body.appendChild(confirmExit); + + // YES button hover effect + const yesBtn = document.getElementById('confirmYes'); + yesBtn.addEventListener('mouseenter', () => { + yesBtn.style.background = '#ff3366'; + yesBtn.style.color = '#000'; + yesBtn.style.transform = 'translateY(-5px) scale(1.08)'; + yesBtn.style.boxShadow = '0 10px 20px rgba(255, 51, 102, 0.6), 0 0 30px #ff3366'; + }); + yesBtn.addEventListener('mouseleave', () => { + yesBtn.style.background = 'linear-gradient(145deg, #111, #1b1b1b)'; + yesBtn.style.color = '#ff3366'; + yesBtn.style.transform = 'translateY(0) scale(1)'; + yesBtn.style.boxShadow = '0 4px 0 #cc0033, 0 0 12px rgba(255, 51, 102, 0.4), inset 0 0 15px rgba(255, 51, 102, 0.1)'; + }); + + // NO button hover effect + const noBtn = document.getElementById('confirmNo'); + noBtn.addEventListener('mouseenter', () => { + noBtn.style.background = '#00eaff'; + noBtn.style.color = '#000'; + noBtn.style.transform = 'translateY(-5px) scale(1.08)'; + noBtn.style.boxShadow = '0 10px 20px rgba(0, 234, 255, 0.6), 0 0 30px #00eaff'; + }); + noBtn.addEventListener('mouseleave', () => { + noBtn.style.background = 'linear-gradient(145deg, #111, #1b1b1b)'; + noBtn.style.color = '#00eaff'; + noBtn.style.transform = 'translateY(0) scale(1)'; + noBtn.style.boxShadow = '0 4px 0 #00bcd4, 0 0 12px rgba(0, 234, 255, 0.4), inset 0 0 15px rgba(0, 234, 255, 0.2)'; + }); + + // Click handlers + yesBtn.addEventListener('click', () => { + window.close(); + setTimeout(() => { + window.location.href = 'about:blank'; + }, 100); + }); + + noBtn.addEventListener('click', () => { + playSound(menuClickSound); + document.body.removeChild(confirmExit); + }); +}); + +// === BACK BUTTON === +backBtn.addEventListener('click', () => { + playSound(menuClickSound); + optionsMenu.style.display = 'none'; + mainMenu.style.display = 'flex'; +}); + +// === MUSIC BUTTONS === +musicBtns.forEach(btn => { + btn.addEventListener('click', () => { + playSound(menuClickSound); + + // Remove active from all + musicBtns.forEach(b => b.classList.remove('active')); + + // Add active to clicked + btn.classList.add('active'); + + // Update setting + gameSettings.musicEnabled = btn.dataset.music === 'on'; + + // Apply immediately if in game + if (typeof currentBGM !== 'undefined') { + if (gameSettings.musicEnabled) { + currentBGM.volume = 1; + if (!game.gameOver && gameStarted) { + currentBGM.play().catch(() => {}); + } + } else { + currentBGM.volume = 0; + currentBGM.pause(); + } + } + }); +}); + +// === SFX BUTTONS === +sfxBtns.forEach(btn => { + btn.addEventListener('click', () => { + playSound(menuClickSound); + + // Remove active from all + sfxBtns.forEach(b => b.classList.remove('active')); + + // Add active to clicked + btn.classList.add('active'); + + // Update setting + gameSettings.sfxEnabled = btn.dataset.sfx === 'on'; + }); +}); + +// === HOVER SOUNDS === +document.querySelectorAll('.menu-btn, .toggle-btn').forEach(btn => { + btn.addEventListener('mouseenter', () => { + if (gameSettings.sfxEnabled) { + playSound(menuHoverSound); + } + }); +}); + +// === APPLY SETTINGS TO GAME === +function applySettings() { + // Apply music setting + if (typeof currentBGM !== 'undefined') { + if (gameSettings.musicEnabled) { + currentBGM.volume = 1; + } else { + currentBGM.volume = 0; + currentBGM.pause(); + } + } + + if (typeof gameOverBGM !== 'undefined') { + if (gameSettings.musicEnabled) { + gameOverBGM.volume = 1; + } else { + gameOverBGM.volume = 0; + } + } +} + +// === PLAY SOUND HELPER === +function playSound(audio) { + if (gameSettings.sfxEnabled) { + audio.volume = 0.3; + audio.currentTime = 0; + audio.play().catch(() => {}); + } +} + +// === KEYBOARD NAVIGATION === +document.addEventListener('keydown', (e) => { + // ESC to go back + if (e.key === 'Escape') { + if (optionsMenu.style.display === 'flex') { + backBtn.click(); + } else if (gameContainer.style.display === 'block' && typeof togglePause !== 'undefined') { + togglePause(); + } + } + + // Enter to start game from main menu + if (e.key === 'Enter' && mainMenu.style.display === 'flex') { + startBtn.click(); + } +}); + +// === MODIFY EXISTING GAME FUNCTIONS === + +// Override window.onload +window.onload = function () { + console.log('Game Ready - Waiting for menu start...'); +}; + +// Add return to menu function +function returnToMenu() { + currentBGM.pause(); + gameOverBGM.pause(); + currentBGM.currentTime = 0; + gameOverBGM.currentTime = 0; + + game.gameOver = false; + game.frames = 0; + game.level = 1; + game.speed = 1; + game.surge = 1.0; + game.surgePhase = 0; + game.surgeTimer = 0; + game.surgeCooldown = 2400; + + missilesArray = []; + playerMissilesArray = []; + enemyShipArray = []; + enemyBulletsArray = []; + explosions = []; + abilityTokens = []; + particles = []; + + player1 = new PlayerObject(100, 300); + player1.lives = 6; + player1.score = 0; + + respawnCounter = 0; + damageFlash = 0; + currentWave = null; + waveCooldown = 0; + abilityCharges = 0; + missileAmmo = 0; + cameraY = 0; + gameStarted = false; + gamePaused = false; + + if (gameContainer) gameContainer.style.display = 'none'; + if (mainMenu) mainMenu.style.display = 'flex'; +} + +console.log('Menu System Loaded'); +console.log('Settings:', gameSettings); \ No newline at end of file diff --git a/Style.css b/Style.css index c224380..1e446d0 100644 --- a/Style.css +++ b/Style.css @@ -1,115 +1,395 @@ +* { + margin: 0; + padding: 0; + box-sizing: border-box; +} + body { - margin: 0; - padding: 0; - background: radial-gradient(circle at center, - rgb(255, 255, 255) 0%, - rgb(255, 150, 50) 20%, - rgb(255, 40, 0) 35%, - rgb(110, 0, 150) 55%, - rgb(5, 10, 35) 100% - ); + margin: 0; + padding: 0; + background-color: #000; + font-family: 'Orbitron', sans-serif; } html, body { - height: 100%; - overflow: hidden; + height: 100%; + overflow: hidden; } -#game { - margin: 0; - padding: 0; - width: 100vw; - height: 100vh; -} - -#canvas { - width: 100%; - height: 100%; - margin: 0; - background-color: black; - display: block; -} - -#startMenu { - position: absolute; - width: 100vw; - height: 100vh; - top: 0; - left: 0; - background: rgba(0, 0, 0, 0.6); - backdrop-filter: blur(6px); - display: flex; - flex-direction: column; - justify-content: center; - align-items: center; - z-index: 10; - font-family: 'Poppins', Arial, sans-serif; - animation: fadeIn 1s ease-out; +/* === MAIN MENU & OPTIONS MENU === */ +#mainMenu, #optionsMenu { + position: absolute; + width: 100vw; + height: 100vh; + top: 0; + left: 0; + background: rgba(0, 0, 0, 0.6); + backdrop-filter: blur(6px); + display: flex; + flex-direction: column; + justify-content: center; + align-items: center; + z-index: 10; + animation: fadeIn 1s ease-out; } @keyframes fadeIn { - from { opacity: 0; } - to { opacity: 1; } + from { opacity: 0; } + to { opacity: 1; } } -.title { - font-size: 90px; - margin-bottom: 40px; - color: #ffffff; - letter-spacing: 4px; - font-weight: 900; - text-shadow: - 2px 2px 0px #00bcd4, - 4px 4px 0px #009bb0, - 6px 6px 0px #007a8c, - 8px 8px 0px #005a68, - 10px 10px 12px rgba(0, 234, 255, 0.7), - 0 0 25px #00eaff; - animation: pixelGlow 2s infinite alternate ease-in-out; +/* === STARS CONTAINER (hidden by default, no animation) === */ +.stars-container { + display: none; +} + +/* === MENU CONTENT === */ +.menu-content { + text-align: center; + z-index: 11; +} + +/* === GAME TITLE === */ +.game-title { + display: flex; + flex-direction: column; + gap: 5px; + margin-bottom: 60px; +} + +.title-word { + font-size: 90px; + color: #ffffff; + letter-spacing: 4px; + font-weight: 900; + text-shadow: + 2px 2px 0px #00bcd4, + 4px 4px 0px #009bb0, + 6px 6px 0px #007a8c, + 8px 8px 0px #005a68, + 10px 10px 12px rgba(0, 234, 255, 0.7), + 0 0 25px #00eaff; + animation: pixelGlow 2s infinite alternate ease-in-out; } @keyframes pixelGlow { - from { - text-shadow: - 2px 2px 0px #00eaff, - 4px 4px 0px #00bcd4, - 6px 6px 0px #009bb0, - 8px 8px 0px #007a8c, - 10px 10px 14px rgba(0, 234, 255, 0.9), - 0 0 35px #00eaff; - } - to { - text-shadow: - 2px 2px 0px #00eaff, - 3px 3px 0px #00bcd4, - 5px 5px 0px #009bb0, - 7px 7px 0px #007a8c, - 9px 9px 12px rgba(0, 234, 255, 0.7), - 0 0 20px #00eaff; - } + from { + text-shadow: + 2px 2px 0px #00eaff, + 4px 4px 0px #00bcd4, + 6px 6px 0px #009bb0, + 8px 8px 0px #007a8c, + 10px 10px 14px rgba(0, 234, 255, 0.9), + 0 0 35px #00eaff; + } + to { + text-shadow: + 2px 2px 0px #00eaff, + 3px 3px 0px #00bcd4, + 5px 5px 0px #009bb0, + 7px 7px 0px #007a8c, + 9px 9px 12px rgba(0, 234, 255, 0.7), + 0 0 20px #00eaff; + } } -.menuButton { - font-size: 28px; - padding: 15px 55px; - margin: 12px; - cursor: pointer; - background: linear-gradient(145deg, #111, #1b1b1b); - color: white; - border: 2px solid #00eaff; - border-radius: 40px; - box-shadow: - 0 4px 0 #00bcd4, - 0 0 12px rgba(0, 234, 255, 0.4), - inset 0 0 15px rgba(0, 234, 255, 0.2); - transition: 0.3s ease-in-out; +/* === MENU BUTTONS CONTAINER === */ +.menu-buttons { + display: flex; + flex-direction: column; + gap: 15px; + margin-bottom: 40px; } -.menuButton:hover { - background: #00eaff; - color: #000; - transform: translateY(-5px) scale(1.08); - box-shadow: - 0 10px 20px rgba(0, 234, 255, 0.6), - 0 0 30px #00eaff; +/* === MENU BUTTON === */ +.menu-btn { + font-size: 28px; + padding: 15px 55px; + margin: 0; + cursor: pointer; + background: linear-gradient(145deg, #111, #1b1b1b); + color: white; + border: 2px solid #00eaff; + border-radius: 40px; + box-shadow: + 0 4px 0 #00bcd4, + 0 0 12px rgba(0, 234, 255, 0.4), + inset 0 0 15px rgba(0, 234, 255, 0.2); + transition: 0.3s ease-in-out; + font-family: 'Orbitron', sans-serif; + font-weight: 700; + text-transform: uppercase; + letter-spacing: 2px; + display: flex; + align-items: center; + justify-content: center; + gap: 12px; + min-width: 320px; } + +.menu-btn:hover { + background: #00eaff; + color: #000; + transform: translateY(-5px) scale(1.08); + box-shadow: + 0 10px 20px rgba(0, 234, 255, 0.6), + 0 0 30px #00eaff; +} + +.menu-btn:active { + transform: translateY(-2px) scale(1.05); +} + +/* === BUTTON ICON & TEXT === */ +.btn-icon { + font-size: 24px; + font-weight: bold; +} + +.btn-text { + font-size: 22px; +} + +/* === FOOTER INFO === */ +.footer-info { + margin-top: 50px; + padding: 20px 30px; + background: rgba(0, 0, 0, 0.4); + border: 2px solid rgba(0, 234, 255, 0.3); + border-radius: 15px; + backdrop-filter: blur(4px); +} + +.footer-info p { + color: #00eaff; + font-size: 14px; + letter-spacing: 1px; + opacity: 0.9; + text-align: center; +} + +/* === OPTIONS TITLE === */ +.options-title { + font-size: 70px; + font-weight: 900; + color: #ffffff; + margin-bottom: 50px; + letter-spacing: 4px; + text-shadow: + 2px 2px 0px #00bcd4, + 4px 4px 0px #009bb0, + 6px 6px 0px #007a8c, + 8px 8px 0px #005a68, + 10px 10px 12px rgba(0, 234, 255, 0.7), + 0 0 25px #00eaff; +} + +/* === OPTIONS CONTAINER === */ +.options-container { + background: rgba(0, 0, 0, 0.5); + border: 2px solid rgba(0, 234, 255, 0.4); + border-radius: 20px; + padding: 40px 50px; + margin-bottom: 40px; + min-width: 600px; + backdrop-filter: blur(5px); + box-shadow: + 0 0 20px rgba(0, 234, 255, 0.3), + inset 0 0 20px rgba(0, 234, 255, 0.1); +} + +/* === OPTION ITEM === */ +.option-item { + margin-bottom: 35px; + text-align: left; +} + +.option-item:last-child { + margin-bottom: 0; +} + +.option-item label { + display: block; + color: #00eaff; + font-size: 20px; + font-weight: 700; + margin-bottom: 15px; + letter-spacing: 2px; + text-transform: uppercase; + text-shadow: 0 0 10px rgba(0, 234, 255, 0.5); +} + +/* === SLIDER CONTAINER === */ +.slider-container { + display: flex; + align-items: center; + gap: 20px; +} + +/* === RANGE SLIDER === */ +input[type="range"] { + flex: 1; + height: 6px; + background: rgba(27, 27, 27, 0.8); + border: 2px solid #00eaff; + border-radius: 10px; + outline: none; + -webkit-appearance: none; + cursor: pointer; + box-shadow: inset 0 0 5px rgba(0, 234, 255, 0.3); +} + +input[type="range"]::-webkit-slider-thumb { + -webkit-appearance: none; + appearance: none; + width: 24px; + height: 24px; + background: linear-gradient(145deg, #00eaff, #00bcd4); + border-radius: 50%; + cursor: pointer; + box-shadow: + 0 0 10px rgba(0, 234, 255, 0.8), + 0 2px 4px rgba(0, 0, 0, 0.5); + transition: all 0.2s ease; + border: 2px solid #ffffff; +} + +input[type="range"]::-webkit-slider-thumb:hover { + background: #00eaff; + box-shadow: + 0 0 20px rgba(0, 234, 255, 1), + 0 4px 8px rgba(0, 0, 0, 0.6); + transform: scale(1.15); +} + +input[type="range"]::-moz-range-thumb { + width: 24px; + height: 24px; + background: linear-gradient(145deg, #00eaff, #00bcd4); + border-radius: 50%; + cursor: pointer; + border: 2px solid #ffffff; + box-shadow: + 0 0 10px rgba(0, 234, 255, 0.8), + 0 2px 4px rgba(0, 0, 0, 0.5); +} + +/* === SLIDER VALUE TEXT === */ +.slider-container span { + color: #ffffff; + font-size: 18px; + font-weight: 700; + min-width: 60px; + text-align: right; + text-shadow: 0 0 8px rgba(0, 234, 255, 0.6); +} + +/* === BUTTON GROUP === */ +.button-group { + display: flex; + gap: 12px; +} + +/* === TOGGLE BUTTON === */ +.toggle-btn { + flex: 1; + padding: 12px 25px; + font-family: 'Orbitron', sans-serif; + font-size: 16px; + font-weight: 600; + color: rgba(255, 255, 255, 0.6); + background: linear-gradient(145deg, #111, #1b1b1b); + border: 2px solid rgba(0, 234, 255, 0.4); + border-radius: 10px; + cursor: pointer; + transition: all 0.3s ease; + text-transform: uppercase; + letter-spacing: 1px; + box-shadow: + 0 2px 0 rgba(0, 188, 212, 0.3), + inset 0 0 10px rgba(0, 234, 255, 0.1); +} + +.toggle-btn:hover { + color: #00eaff; + border-color: #00eaff; + background: linear-gradient(145deg, #1b1b1b, #2a2a2a); + box-shadow: + 0 2px 0 #00bcd4, + 0 0 15px rgba(0, 234, 255, 0.4), + inset 0 0 15px rgba(0, 234, 255, 0.2); +} + +.toggle-btn.active { + color: #000; + background: #00eaff; + border-color: #00eaff; + box-shadow: + 0 4px 0 #00bcd4, + 0 0 20px rgba(0, 234, 255, 0.8), + inset 0 0 10px rgba(255, 255, 255, 0.3); + transform: translateY(-2px); +} + +/* === BACK BUTTON === */ +.back-btn { + margin-top: 20px; + background: linear-gradient(145deg, #1b1b1b, #111); + border-color: #00eaff; + color: #00eaff; + box-shadow: + 0 4px 0 #00bcd4, + 0 0 12px rgba(0, 234, 255, 0.4), + inset 0 0 15px rgba(0, 234, 255, 0.2); +} + +.back-btn:hover { + background: linear-gradient(145deg, #2a2a2a, #1b1b1b); + border-color: #00eaff; + color: #ffffff; + box-shadow: + 0 6px 0 #00bcd4, + 0 0 25px rgba(0, 234, 255, 0.6), + inset 0 0 20px rgba(0, 234, 255, 0.3); +} + +/* === GAME CONTAINER === */ +#gameContainer { + width: 100vw; + height: 100vh; + background: #000; +} + +#canvas { + width: 100%; + height: 100%; + margin: 0; + background-color: black; + display: block; +} + +/* === RESPONSIVE === */ +@media (max-width: 768px) { + .title-word { + font-size: 60px; + } + + .menu-btn { + font-size: 20px; + padding: 12px 40px; + min-width: 280px; + } + + .options-container { + min-width: 90vw; + padding: 30px; + } + + .options-title { + font-size: 50px; + } + + .footer-info p { + font-size: 12px; + } +} \ No newline at end of file