diff --git a/cmd/client/draw_wasm.go b/cmd/client/draw_wasm.go index 90e96de..98a6e68 100644 --- a/cmd/client/draw_wasm.go +++ b/cmd/client/draw_wasm.go @@ -9,8 +9,8 @@ import ( "github.com/hajimehoshi/ebiten/v2" ) -// In WASM: Menü und Leaderboard werden in HTML angezeigt -// Lobby wird aber normal gezeichnet (für Co-op Warteraum) +// In WASM: Menü, Lobby und Leaderboard werden in HTML angezeigt +// Canvas zeigt nur das eigentliche Spiel func (g *Game) drawMenu(screen *ebiten.Image) { // Schwarzer Hintergrund - HTML-Menü ist darüber @@ -18,8 +18,8 @@ func (g *Game) drawMenu(screen *ebiten.Image) { } func (g *Game) drawLobby(screen *ebiten.Image) { - // Lobby wird normal gezeichnet (für Co-op Warteraum) - g.DrawLobby(screen) + // Schwarzer Hintergrund - HTML-Lobby ist darüber + screen.Fill(color.RGBA{0, 0, 0, 255}) } func (g *Game) drawLeaderboard(screen *ebiten.Image) { diff --git a/cmd/client/main.go b/cmd/client/main.go index 3d08f63..bc771ce 100644 --- a/cmd/client/main.go +++ b/cmd/client/main.go @@ -355,6 +355,16 @@ func (g *Game) updateLobby() { g.gameState = game.GameState{Players: make(map[string]game.PlayerState)} } + // Lobby State Change Detection (für HTML-Updates) + g.stateMutex.Lock() + currentPlayerCount := len(g.gameState.Players) + g.stateMutex.Unlock() + + if currentPlayerCount != g.lastPlayerCount { + g.lastPlayerCount = currentPlayerCount + g.sendLobbyUpdateToJS() + } + // Spiel wurde gestartet? if g.gameState.Status == "COUNTDOWN" || g.gameState.Status == "RUNNING" { g.appState = StateGame diff --git a/cmd/client/wasm_bridge.go b/cmd/client/wasm_bridge.go index 62ee9f7..7187edb 100644 --- a/cmd/client/wasm_bridge.go +++ b/cmd/client/wasm_bridge.go @@ -80,11 +80,19 @@ func (g *Game) setupJavaScriptBridge() { return nil }) + // startGameFromLobby_WASM() - Host startet Spiel aus HTML Lobby + startGameFromLobbyFunc := js.FuncOf(func(this js.Value, args []js.Value) interface{} { + log.Println("🎮 Host startet Spiel aus HTML Lobby") + go g.sendStartRequest() + return nil + }) + // Im globalen Scope registrieren js.Global().Set("startGame", startGameFunc) js.Global().Set("requestLeaderboard", requestLeaderboardFunc) js.Global().Set("setMusicVolume", setMusicVolumeFunc) js.Global().Set("setSFXVolume", setSFXVolumeFunc) + js.Global().Set("startGameFromLobby_WASM", startGameFromLobbyFunc) log.Println("✅ JavaScript Bridge registriert") } @@ -117,3 +125,30 @@ func (g *Game) sendGameOverToJS(score int) { log.Printf("💀 Game Over an JavaScript gesendet: Score=%d", score) } } + +// Lobby Player List an JavaScript senden +func (g *Game) sendLobbyPlayersToJS() { + g.stateMutex.Lock() + players := make([]interface{}, 0, len(g.gameState.Players)) + hostID := g.gameState.HostID + + for id, p := range g.gameState.Players { + name := p.Name + if name == "" { + name = id + } + isHost := (id == hostID) + players = append(players, map[string]interface{}{ + "name": name, + "is_host": isHost, + }) + } + g.stateMutex.Unlock() + + // JavaScript-Funktion aufrufen + if updateFunc := js.Global().Get("updateLobbyPlayers"); !updateFunc.IsUndefined() { + jsPlayers := js.ValueOf(players) + updateFunc.Invoke(jsPlayers) + log.Printf("👥 Lobby-Spieler an JavaScript gesendet: %d Spieler", len(players)) + } +} diff --git a/cmd/client/web/game.js b/cmd/client/web/game.js index 24a56a5..c46fed9 100644 --- a/cmd/client/web/game.js +++ b/cmd/client/web/game.js @@ -91,10 +91,17 @@ function startSoloGame() { localStorage.setItem('escape_game_mode', 'solo'); localStorage.setItem('escape_room_id', ''); - // Hide menu and show canvas + // 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, ''); @@ -120,17 +127,17 @@ function createRoom() { localStorage.setItem('escape_team_name', teamName); localStorage.setItem('escape_is_host', 'true'); - // Hide menu and show canvas (Lobby wird vom WASM gezeichnet) + // Verstecke ALLE Screens inkl. Hauptmenü hideAllScreens(); - gameStarted = true; + document.getElementById('menu').style.display = 'none'; - // Canvas sichtbar machen für Lobby - const canvas = document.querySelector('canvas'); - if (canvas) { - canvas.classList.add('game-active'); - } + // 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 + // Trigger WASM game start (im Hintergrund) if (window.startGame) { window.startGame('coop', playerName, roomID, teamName, true); } @@ -160,17 +167,17 @@ function joinRoom() { localStorage.setItem('escape_team_name', teamName); localStorage.setItem('escape_is_host', 'false'); - // Hide menu and show canvas + // Verstecke ALLE Screens inkl. Hauptmenü hideAllScreens(); - gameStarted = true; + document.getElementById('menu').style.display = 'none'; - // Canvas sichtbar machen für Lobby - const canvas = document.querySelector('canvas'); - if (canvas) { - canvas.classList.add('game-active'); - } + // 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 + // Trigger WASM game start (im Hintergrund) if (window.startGame) { window.startGame('coop', playerName, roomID, teamName, false); } @@ -178,6 +185,47 @@ function joinRoom() { 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 = '
Warte auf Spieler...
'; + return; + } + + list.innerHTML = players.map((player, index) => { + const hostBadge = player.is_host ? ' [HOST]' : ''; + return `
• ${player.name}${hostBadge}
`; + }).join(''); + + console.log('👥 Lobby players updated:', players.length); +} + function loadLeaderboard() { const list = document.getElementById('leaderboardList'); list.innerHTML = '
Lädt Leaderboard...
'; @@ -197,16 +245,16 @@ function loadLeaderboard() { // Called by WASM to update leaderboard function updateLeaderboard(entries) { - // Update main leaderboard page + // Update ALL leaderboard displays const list = document.getElementById('leaderboardList'); - - // Update start screen leaderboard const startList = document.getElementById('startLeaderboardList'); + const gameOverList = document.getElementById('gameOverLeaderboardList'); if (!entries || entries.length === 0) { const emptyMsg = '
Noch keine Einträge
'; if (list) list.innerHTML = emptyMsg; if (startList) startList.innerHTML = emptyMsg; + if (gameOverList) gameOverList.innerHTML = emptyMsg; return; } @@ -223,6 +271,7 @@ function updateLeaderboard(entries) { if (list) list.innerHTML = html; if (startList) startList.innerHTML = html; + if (gameOverList) gameOverList.innerHTML = html; console.log('📊 Leaderboard updated with', entries.length, 'entries'); } diff --git a/cmd/client/web/index.html b/cmd/client/web/index.html index b9078a5..56398d5 100644 --- a/cmd/client/web/index.html +++ b/cmd/client/web/index.html @@ -5,6 +5,19 @@ Escape From Teacher + @@ -115,6 +128,35 @@ + + +