Private
Public Access
1
0
Files
EscapeFromTeacher/cmd/client/web/game.js

391 lines
12 KiB
JavaScript

// Game State
let wasmReady = false;
let gameStarted = false;
let audioMuted = false;
// Initialize WASM
async function initWASM() {
const go = new Go();
try {
const result = await WebAssembly.instantiateStreaming(fetch("main.wasm"), go.importObject);
go.run(result.instance);
wasmReady = true;
// Hide loading screen
document.getElementById('loading').style.display = 'none';
console.log('✅ WASM loaded successfully');
// Load initial leaderboard
setTimeout(() => {
if (window.requestLeaderboard) {
window.requestLeaderboard();
}
}, 500);
} catch (err) {
console.error('❌ Failed to load WASM:', err);
document.getElementById('loading').innerHTML = '<div class="spinner"></div><p>Fehler beim Laden: ' + err.message + '</p>';
}
}
// Menu Navigation
function showMainMenu() {
hideAllScreens();
document.getElementById('menu').classList.remove('hidden');
}
function showCoopMenu() {
hideAllScreens();
document.getElementById('coopMenu').classList.remove('hidden');
}
function showSettings() {
hideAllScreens();
document.getElementById('settingsMenu').classList.remove('hidden');
}
function showLeaderboard() {
hideAllScreens();
document.getElementById('leaderboardMenu').classList.remove('hidden');
loadLeaderboard();
}
function hideAllScreens() {
document.querySelectorAll('.overlay-screen').forEach(screen => {
screen.classList.add('hidden');
});
}
function hideMenu() {
document.getElementById('menu').style.display = 'none';
// Canvas sichtbar machen für Gameplay
const canvas = document.querySelector('canvas');
if (canvas) {
canvas.classList.add('game-active');
}
}
function showMenu() {
document.getElementById('menu').style.display = 'flex';
document.getElementById('menu').classList.remove('hidden');
showMainMenu();
// Canvas verstecken im Menü
const canvas = document.querySelector('canvas');
if (canvas) {
canvas.classList.remove('game-active');
}
}
// Game Functions
function startSoloGame() {
if (!wasmReady) {
alert('Spiel wird noch geladen...');
return;
}
const playerName = document.getElementById('playerName').value || 'ANON';
// Store in localStorage for WASM to read
localStorage.setItem('escape_player_name', playerName);
localStorage.setItem('escape_game_mode', 'solo');
localStorage.setItem('escape_room_id', '');
// Hide ALL screens including main menu
hideAllScreens();
document.getElementById('menu').style.display = 'none';
gameStarted = true;
// Canvas sichtbar machen
const canvas = document.querySelector('canvas');
if (canvas) {
canvas.classList.add('game-active');
}
// Trigger WASM game start
if (window.startGame) {
window.startGame('solo', playerName, '');
}
console.log('🎮 Solo game started:', playerName);
}
function createRoom() {
if (!wasmReady) {
alert('Spiel wird noch geladen...');
return;
}
const playerName = document.getElementById('playerName').value || 'ANON';
const roomID = 'R' + Math.random().toString(36).substr(2, 5).toUpperCase();
const teamName = 'TEAM';
// Store in localStorage
localStorage.setItem('escape_player_name', playerName);
localStorage.setItem('escape_game_mode', 'coop');
localStorage.setItem('escape_room_id', roomID);
localStorage.setItem('escape_team_name', teamName);
localStorage.setItem('escape_is_host', 'true');
// Verstecke ALLE Screens inkl. Hauptmenü
hideAllScreens();
document.getElementById('menu').style.display = 'none';
// Zeige HTML Lobby Screen
document.getElementById('lobbyScreen').classList.remove('hidden');
document.getElementById('lobbyRoomCode').textContent = roomID;
document.getElementById('lobbyHostControls').classList.remove('hidden');
document.getElementById('lobbyStatus').textContent = 'Du bist Host - starte wenn bereit!';
// Trigger WASM game start (im Hintergrund)
if (window.startGame) {
window.startGame('coop', playerName, roomID, teamName, true);
}
console.log('🎮 Room created:', roomID);
}
function joinRoom() {
if (!wasmReady) {
alert('Spiel wird noch geladen...');
return;
}
const playerName = document.getElementById('playerName').value || 'ANON';
const roomID = document.getElementById('joinRoomCode').value.toUpperCase();
const teamName = document.getElementById('teamNameJoin').value || 'TEAM';
if (!roomID || roomID.length < 4) {
alert('Bitte gib einen gültigen Raum-Code ein!');
return;
}
// Store in localStorage
localStorage.setItem('escape_player_name', playerName);
localStorage.setItem('escape_game_mode', 'coop');
localStorage.setItem('escape_room_id', roomID);
localStorage.setItem('escape_team_name', teamName);
localStorage.setItem('escape_is_host', 'false');
// Verstecke ALLE Screens inkl. Hauptmenü
hideAllScreens();
document.getElementById('menu').style.display = 'none';
// Zeige HTML Lobby Screen
document.getElementById('lobbyScreen').classList.remove('hidden');
document.getElementById('lobbyRoomCode').textContent = roomID;
document.getElementById('lobbyHostControls').classList.add('hidden');
document.getElementById('lobbyStatus').textContent = 'Warte auf Host...';
// Trigger WASM game start (im Hintergrund)
if (window.startGame) {
window.startGame('coop', playerName, roomID, teamName, false);
}
console.log('🎮 Joining room:', roomID);
}
// Lobby Functions
function startGameFromLobby() {
// Host startet das Spiel
hideAllScreens();
document.getElementById('menu').style.display = 'none';
gameStarted = true;
// Canvas sichtbar machen
const canvas = document.querySelector('canvas');
if (canvas) {
canvas.classList.add('game-active');
}
// Signal an WASM senden dass Spiel starten soll
if (window.startGameFromLobby_WASM) {
window.startGameFromLobby_WASM();
}
console.log('🎮 Host started game from lobby');
}
function leaveLobby() {
location.reload();
}
// Update Lobby Player List (called by WASM)
function updateLobbyPlayers(players) {
const list = document.getElementById('lobbyPlayerList');
if (!players || players.length === 0) {
list.innerHTML = '<div style="color: #888;">Warte auf Spieler...</div>';
return;
}
list.innerHTML = players.map((player, index) => {
const hostBadge = player.is_host ? ' <span style="color:#ffcc00;">[HOST]</span>' : '';
return `<div style="padding:5px 0; color:#fff;">• ${player.name}${hostBadge}</div>`;
}).join('');
console.log('👥 Lobby players updated:', players.length);
}
function loadLeaderboard() {
const list = document.getElementById('leaderboardList');
list.innerHTML = '<div style="text-align:center; padding:20px;">Lädt Leaderboard...</div>';
// Request leaderboard from WASM
if (window.requestLeaderboard) {
window.requestLeaderboard();
}
// Fallback timeout
setTimeout(() => {
if (list.innerHTML.includes('Lädt')) {
list.innerHTML = '<div style="text-align:center; padding:20px; color:#888;">Keine Daten verfügbar</div>';
}
}, 3000);
}
// Called by WASM to update leaderboard
function updateLeaderboard(entries) {
// Update ALL leaderboard displays
const list = document.getElementById('leaderboardList');
const startList = document.getElementById('startLeaderboardList');
const gameOverList = document.getElementById('gameOverLeaderboardList');
if (!entries || entries.length === 0) {
const emptyMsg = '<div style="text-align:center; padding:20px; color:#888;">Noch keine Einträge</div>';
if (list) list.innerHTML = emptyMsg;
if (startList) startList.innerHTML = emptyMsg;
if (gameOverList) gameOverList.innerHTML = emptyMsg;
return;
}
const html = entries.slice(0, 10).map((entry, index) => {
const medal = index === 0 ? '🥇' : index === 1 ? '🥈' : index === 2 ? '🥉' : `${index + 1}.`;
return `
<div class="leaderboard-item">
<div class="leaderboard-rank">${medal}</div>
<div class="leaderboard-name">${entry.player_name}</div>
<div class="leaderboard-score">${entry.score}</div>
</div>
`;
}).join('');
if (list) list.innerHTML = html;
if (startList) startList.innerHTML = html;
if (gameOverList) gameOverList.innerHTML = html;
console.log('📊 Leaderboard updated with', entries.length, 'entries');
}
// Audio Toggle
function toggleAudio() {
audioMuted = !audioMuted;
const btn = document.getElementById('mute-btn');
if (audioMuted) {
btn.textContent = '🔇';
if (window.setMusicVolume) window.setMusicVolume(0);
if (window.setSFXVolume) window.setSFXVolume(0);
} else {
btn.textContent = '🔊';
const musicVol = parseInt(localStorage.getItem('escape_music_volume') || 70) / 100;
const sfxVol = parseInt(localStorage.getItem('escape_sfx_volume') || 70) / 100;
if (window.setMusicVolume) window.setMusicVolume(musicVol);
if (window.setSFXVolume) window.setSFXVolume(sfxVol);
}
}
// Settings Volume Sliders
document.addEventListener('DOMContentLoaded', () => {
const musicSlider = document.getElementById('musicVolume');
const sfxSlider = document.getElementById('sfxVolume');
const musicValue = document.getElementById('musicValue');
const sfxValue = document.getElementById('sfxValue');
if (musicSlider) {
musicSlider.addEventListener('input', (e) => {
const value = e.target.value;
musicValue.textContent = value + '%';
localStorage.setItem('escape_music_volume', value);
if (window.setMusicVolume && !audioMuted) {
window.setMusicVolume(value / 100);
}
});
// Load saved value
const savedMusic = localStorage.getItem('escape_music_volume') || 70;
musicSlider.value = savedMusic;
musicValue.textContent = savedMusic + '%';
}
if (sfxSlider) {
sfxSlider.addEventListener('input', (e) => {
const value = e.target.value;
sfxValue.textContent = value + '%';
localStorage.setItem('escape_sfx_volume', value);
if (window.setSFXVolume && !audioMuted) {
window.setSFXVolume(value / 100);
}
});
// Load saved value
const savedSFX = localStorage.getItem('escape_sfx_volume') || 70;
sfxSlider.value = savedSFX;
sfxValue.textContent = savedSFX + '%';
}
// Load saved player name
const savedName = localStorage.getItem('escape_player_name');
if (savedName) {
document.getElementById('playerName').value = savedName;
}
// Load local highscore
const highscore = localStorage.getItem('escape_local_highscore') || 0;
const hsElement = document.getElementById('localHighscore');
if (hsElement) {
hsElement.textContent = highscore;
}
});
// Keyboard shortcuts
document.addEventListener('keydown', (e) => {
// ESC to show menu (only if game is started)
if (e.key === 'Escape' && gameStarted) {
showMenu();
gameStarted = false;
}
});
// Show Game Over Screen (called by WASM)
function showGameOver(score) {
hideAllScreens();
document.getElementById('gameOverScreen').classList.remove('hidden');
document.getElementById('finalScore').textContent = score;
// Update local highscore
const currentHS = parseInt(localStorage.getItem('escape_local_highscore') || 0);
if (score > currentHS) {
localStorage.setItem('escape_local_highscore', score);
}
// Request leaderboard
if (window.requestLeaderboard) {
window.requestLeaderboard();
}
console.log('💀 Game Over! Score:', score);
}
// Export functions for WASM to call
window.showMenu = showMenu;
window.hideMenu = hideMenu;
window.updateLeaderboard = updateLeaderboard;
window.showGameOver = showGameOver;
// Initialize on load
initWASM();
console.log('🎮 Game.js loaded - Retro Edition');