Integrate direct WebSocket-based leaderboard functionality for real-time updates and requests. Refactor related client-side logic to utilize this new connection.
This commit is contained in:
@@ -190,6 +190,17 @@ func (g *Game) connectForLeaderboard() {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Temporäre Daten für Leaderboard-Verbindung
|
||||||
|
if g.playerName == "" {
|
||||||
|
g.playerName = "LeaderboardViewer"
|
||||||
|
}
|
||||||
|
if g.roomID == "" {
|
||||||
|
g.roomID = "leaderboard_only"
|
||||||
|
}
|
||||||
|
if g.gameMode == "" {
|
||||||
|
g.gameMode = "solo"
|
||||||
|
}
|
||||||
|
|
||||||
// Neue Verbindung aufbauen
|
// Neue Verbindung aufbauen
|
||||||
g.connectToServer()
|
g.connectToServer()
|
||||||
|
|
||||||
@@ -200,6 +211,13 @@ func (g *Game) connectForLeaderboard() {
|
|||||||
|
|
||||||
// requestLeaderboard fordert das Leaderboard an
|
// requestLeaderboard fordert das Leaderboard an
|
||||||
func (g *Game) requestLeaderboard() {
|
func (g *Game) requestLeaderboard() {
|
||||||
|
// Verbindung aufbauen falls nicht vorhanden
|
||||||
|
if g.wsConn == nil || !g.wsConn.connected {
|
||||||
|
log.Println("📡 Keine Verbindung für Leaderboard, stelle Verbindung her...")
|
||||||
|
go g.connectForLeaderboard()
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
mode := "solo"
|
mode := "solo"
|
||||||
if g.gameMode == "coop" {
|
if g.gameMode == "coop" {
|
||||||
mode = "coop"
|
mode = "coop"
|
||||||
|
|||||||
9
cmd/client/gamestart_native.go
Normal file
9
cmd/client/gamestart_native.go
Normal file
@@ -0,0 +1,9 @@
|
|||||||
|
//go:build !wasm
|
||||||
|
// +build !wasm
|
||||||
|
|
||||||
|
package main
|
||||||
|
|
||||||
|
// notifyGameStarted ist ein Stub für native Builds
|
||||||
|
func (g *Game) notifyGameStarted() {
|
||||||
|
// Native hat kein JavaScript-Interface
|
||||||
|
}
|
||||||
17
cmd/client/gamestart_wasm.go
Normal file
17
cmd/client/gamestart_wasm.go
Normal file
@@ -0,0 +1,17 @@
|
|||||||
|
//go:build js && wasm
|
||||||
|
// +build js,wasm
|
||||||
|
|
||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"log"
|
||||||
|
"syscall/js"
|
||||||
|
)
|
||||||
|
|
||||||
|
// notifyGameStarted benachrichtigt JavaScript dass das Spiel startet
|
||||||
|
func (g *Game) notifyGameStarted() {
|
||||||
|
if startFunc := js.Global().Get("onGameStarted"); !startFunc.IsUndefined() {
|
||||||
|
startFunc.Invoke()
|
||||||
|
log.Println("🎮 Game Started - Benachrichtigung an JavaScript gesendet")
|
||||||
|
}
|
||||||
|
}
|
||||||
9
cmd/client/lobby_native.go
Normal file
9
cmd/client/lobby_native.go
Normal file
@@ -0,0 +1,9 @@
|
|||||||
|
//go:build !wasm
|
||||||
|
// +build !wasm
|
||||||
|
|
||||||
|
package main
|
||||||
|
|
||||||
|
// sendLobbyUpdateToJS ist ein Stub für native Builds (kein HTML-Interface)
|
||||||
|
func (g *Game) sendLobbyUpdateToJS() {
|
||||||
|
// Native hat kein HTML-Overlay, nichts zu tun
|
||||||
|
}
|
||||||
9
cmd/client/lobby_wasm.go
Normal file
9
cmd/client/lobby_wasm.go
Normal file
@@ -0,0 +1,9 @@
|
|||||||
|
//go:build js && wasm
|
||||||
|
// +build js,wasm
|
||||||
|
|
||||||
|
package main
|
||||||
|
|
||||||
|
// sendLobbyUpdateToJS sendet Lobby-Updates an das HTML-Interface
|
||||||
|
func (g *Game) sendLobbyUpdateToJS() {
|
||||||
|
g.sendLobbyPlayersToJS()
|
||||||
|
}
|
||||||
@@ -367,7 +367,10 @@ func (g *Game) updateLobby() {
|
|||||||
|
|
||||||
// Spiel wurde gestartet?
|
// Spiel wurde gestartet?
|
||||||
if g.gameState.Status == "COUNTDOWN" || g.gameState.Status == "RUNNING" {
|
if g.gameState.Status == "COUNTDOWN" || g.gameState.Status == "RUNNING" {
|
||||||
g.appState = StateGame
|
if g.appState != StateGame {
|
||||||
|
g.appState = StateGame
|
||||||
|
g.notifyGameStarted() // Benachrichtige JavaScript dass Spiel startet
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -3,6 +3,83 @@ let wasmReady = false;
|
|||||||
let gameStarted = false;
|
let gameStarted = false;
|
||||||
let audioMuted = false;
|
let audioMuted = false;
|
||||||
|
|
||||||
|
// WebSocket for Leaderboard (direct JS connection)
|
||||||
|
let leaderboardWS = null;
|
||||||
|
let leaderboardSessionID = 'lb_' + Date.now() + '_' + Math.random().toString(36).substr(2, 9);
|
||||||
|
|
||||||
|
function connectLeaderboardWebSocket() {
|
||||||
|
if (leaderboardWS && leaderboardWS.readyState === WebSocket.OPEN) {
|
||||||
|
return; // Already connected
|
||||||
|
}
|
||||||
|
|
||||||
|
const wsURL = 'ws://localhost:8080/ws';
|
||||||
|
leaderboardWS = new WebSocket(wsURL);
|
||||||
|
|
||||||
|
leaderboardWS.onopen = () => {
|
||||||
|
console.log('📡 Leaderboard WebSocket connected with session:', leaderboardSessionID);
|
||||||
|
|
||||||
|
// Send JOIN message to register session
|
||||||
|
const joinMsg = JSON.stringify({
|
||||||
|
type: 'join',
|
||||||
|
payload: {
|
||||||
|
name: leaderboardSessionID,
|
||||||
|
room_id: 'leaderboard_viewer',
|
||||||
|
game_mode: 'solo',
|
||||||
|
is_host: false,
|
||||||
|
team_name: ''
|
||||||
|
}
|
||||||
|
});
|
||||||
|
leaderboardWS.send(joinMsg);
|
||||||
|
console.log('📝 Registered leaderboard session:', leaderboardSessionID);
|
||||||
|
};
|
||||||
|
|
||||||
|
leaderboardWS.onmessage = (event) => {
|
||||||
|
try {
|
||||||
|
const msg = JSON.parse(event.data);
|
||||||
|
|
||||||
|
if (msg.type === 'leaderboard_response') {
|
||||||
|
console.log('📊 Received leaderboard:', msg.payload?.entries?.length || 0, 'entries');
|
||||||
|
updateLeaderboard(msg.payload?.entries || []);
|
||||||
|
}
|
||||||
|
} catch (e) {
|
||||||
|
console.error('Failed to parse WebSocket message:', e);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
leaderboardWS.onerror = (error) => {
|
||||||
|
console.error('❌ Leaderboard WebSocket error:', error);
|
||||||
|
};
|
||||||
|
|
||||||
|
leaderboardWS.onclose = () => {
|
||||||
|
console.log('📡 Leaderboard WebSocket closed');
|
||||||
|
leaderboardWS = null;
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
function requestLeaderboardDirect() {
|
||||||
|
connectLeaderboardWebSocket();
|
||||||
|
|
||||||
|
// Wait for connection then request
|
||||||
|
const checkAndRequest = setInterval(() => {
|
||||||
|
if (leaderboardWS && leaderboardWS.readyState === WebSocket.OPEN) {
|
||||||
|
clearInterval(checkAndRequest);
|
||||||
|
|
||||||
|
const msg = JSON.stringify({
|
||||||
|
type: 'leaderboard_request',
|
||||||
|
payload: {
|
||||||
|
mode: 'solo',
|
||||||
|
limit: 10
|
||||||
|
}
|
||||||
|
});
|
||||||
|
leaderboardWS.send(msg);
|
||||||
|
console.log('📤 Requesting leaderboard via WebSocket (session:', leaderboardSessionID + ')');
|
||||||
|
}
|
||||||
|
}, 100);
|
||||||
|
|
||||||
|
// Timeout after 3 seconds
|
||||||
|
setTimeout(() => clearInterval(checkAndRequest), 3000);
|
||||||
|
}
|
||||||
|
|
||||||
// Initialize WASM
|
// Initialize WASM
|
||||||
async function initWASM() {
|
async function initWASM() {
|
||||||
const go = new Go();
|
const go = new Go();
|
||||||
@@ -17,11 +94,9 @@ async function initWASM() {
|
|||||||
|
|
||||||
console.log('✅ WASM loaded successfully');
|
console.log('✅ WASM loaded successfully');
|
||||||
|
|
||||||
// Load initial leaderboard
|
// Load initial leaderboard via direct WebSocket
|
||||||
setTimeout(() => {
|
setTimeout(() => {
|
||||||
if (window.requestLeaderboard) {
|
requestLeaderboardDirect();
|
||||||
window.requestLeaderboard();
|
|
||||||
}
|
|
||||||
}, 500);
|
}, 500);
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
console.error('❌ Failed to load WASM:', err);
|
console.error('❌ Failed to load WASM:', err);
|
||||||
@@ -187,23 +262,13 @@ function joinRoom() {
|
|||||||
|
|
||||||
// Lobby Functions
|
// Lobby Functions
|
||||||
function startGameFromLobby() {
|
function startGameFromLobby() {
|
||||||
// Host startet das Spiel
|
// Host startet das Spiel - Lobby bleibt sichtbar bis Server COUNTDOWN/RUNNING sendet
|
||||||
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
|
// Signal an WASM senden dass Spiel starten soll
|
||||||
if (window.startGameFromLobby_WASM) {
|
if (window.startGameFromLobby_WASM) {
|
||||||
window.startGameFromLobby_WASM();
|
window.startGameFromLobby_WASM();
|
||||||
}
|
}
|
||||||
|
|
||||||
console.log('🎮 Host started game from lobby');
|
console.log('🎮 Host requested game start - waiting for server...');
|
||||||
}
|
}
|
||||||
|
|
||||||
function leaveLobby() {
|
function leaveLobby() {
|
||||||
@@ -230,14 +295,12 @@ function loadLeaderboard() {
|
|||||||
const list = document.getElementById('leaderboardList');
|
const list = document.getElementById('leaderboardList');
|
||||||
list.innerHTML = '<div style="text-align:center; padding:20px;">Lädt Leaderboard...</div>';
|
list.innerHTML = '<div style="text-align:center; padding:20px;">Lädt Leaderboard...</div>';
|
||||||
|
|
||||||
// Request leaderboard from WASM
|
// Request leaderboard via direct WebSocket
|
||||||
if (window.requestLeaderboard) {
|
requestLeaderboardDirect();
|
||||||
window.requestLeaderboard();
|
|
||||||
}
|
|
||||||
|
|
||||||
// Fallback timeout
|
// Fallback timeout
|
||||||
setTimeout(() => {
|
setTimeout(() => {
|
||||||
if (list.innerHTML.includes('Lädt')) {
|
if (list && list.innerHTML.includes('Lädt')) {
|
||||||
list.innerHTML = '<div style="text-align:center; padding:20px; color:#888;">Keine Daten verfügbar</div>';
|
list.innerHTML = '<div style="text-align:center; padding:20px; color:#888;">Keine Daten verfügbar</div>';
|
||||||
}
|
}
|
||||||
}, 3000);
|
}, 3000);
|
||||||
@@ -370,19 +433,32 @@ function showGameOver(score) {
|
|||||||
localStorage.setItem('escape_local_highscore', score);
|
localStorage.setItem('escape_local_highscore', score);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Request leaderboard
|
// Request leaderboard via direct WebSocket
|
||||||
if (window.requestLeaderboard) {
|
requestLeaderboardDirect();
|
||||||
window.requestLeaderboard();
|
|
||||||
}
|
|
||||||
|
|
||||||
console.log('💀 Game Over! Score:', score);
|
console.log('💀 Game Over! Score:', score);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Called by WASM when game actually starts
|
||||||
|
function onGameStarted() {
|
||||||
|
console.log('🎮 Game Started - Making canvas visible');
|
||||||
|
hideAllScreens();
|
||||||
|
document.getElementById('menu').style.display = 'none';
|
||||||
|
gameStarted = true;
|
||||||
|
|
||||||
|
// Canvas sichtbar machen
|
||||||
|
const canvas = document.querySelector('canvas');
|
||||||
|
if (canvas) {
|
||||||
|
canvas.classList.add('game-active');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Export functions for WASM to call
|
// Export functions for WASM to call
|
||||||
window.showMenu = showMenu;
|
window.showMenu = showMenu;
|
||||||
window.hideMenu = hideMenu;
|
window.hideMenu = hideMenu;
|
||||||
window.updateLeaderboard = updateLeaderboard;
|
window.updateLeaderboard = updateLeaderboard;
|
||||||
window.showGameOver = showGameOver;
|
window.showGameOver = showGameOver;
|
||||||
|
window.onGameStarted = onGameStarted;
|
||||||
|
|
||||||
// Initialize on load
|
// Initialize on load
|
||||||
initWASM();
|
initWASM();
|
||||||
|
|||||||
@@ -5,19 +5,6 @@
|
|||||||
<meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no, viewport-fit=cover">
|
<meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no, viewport-fit=cover">
|
||||||
<title>Escape From Teacher</title>
|
<title>Escape From Teacher</title>
|
||||||
<link rel="stylesheet" href="style.css">
|
<link rel="stylesheet" href="style.css">
|
||||||
<style>
|
|
||||||
/* DEBUG: Force menu visibility */
|
|
||||||
#menu {
|
|
||||||
position: fixed !important;
|
|
||||||
top: 0 !important;
|
|
||||||
left: 0 !important;
|
|
||||||
width: 100% !important;
|
|
||||||
height: 100% !important;
|
|
||||||
background: rgba(0, 0, 0, 0.95) !important;
|
|
||||||
z-index: 10000 !important;
|
|
||||||
display: flex !important;
|
|
||||||
}
|
|
||||||
</style>
|
|
||||||
</head>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
|
|
||||||
|
|||||||
Binary file not shown.
BIN
cmd/client/web/pc-trash.png
Normal file
BIN
cmd/client/web/pc-trash.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 4.2 MiB |
25
cmd/client/web/test_visibility.html
Normal file
25
cmd/client/web/test_visibility.html
Normal file
@@ -0,0 +1,25 @@
|
|||||||
|
<!DOCTYPE html>
|
||||||
|
<html>
|
||||||
|
<head>
|
||||||
|
<style>
|
||||||
|
body { margin: 0; padding: 0; background: red; }
|
||||||
|
.test-menu {
|
||||||
|
position: fixed;
|
||||||
|
top: 0;
|
||||||
|
left: 0;
|
||||||
|
width: 100%;
|
||||||
|
height: 100%;
|
||||||
|
background: rgba(0,0,0,0.9);
|
||||||
|
z-index: 1000;
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
color: white;
|
||||||
|
font-size: 48px;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<div class="test-menu">TEST - SIEHST DU MICH?</div>
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
Reference in New Issue
Block a user