Private
Public Access
1
0
Files
EscapeFromTeacher/cmd/client/web/index.html
Sebastian Unterschütz af08c13255
All checks were successful
Dynamic Branch Deploy / build-and-deploy (push) Successful in 8m27s
refactor client prediction logic and add tolerance levels; implement restartGame function to reset game state without a full reload
2026-01-28 12:01:15 +01:00

301 lines
15 KiB
HTML

<!DOCTYPE html>
<html lang="de">
<head>
<meta charset="UTF-8">
<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>
<link rel="stylesheet" href="style.css">
</head>
<body>
<button id="mute-btn" onclick="toggleAudio()">🔊</button>
<div id="rotate-overlay">
<div class="icon">📱↻</div>
<p>Bitte Gerät drehen!</p>
<small>Querformat benötigt</small>
</div>
<div id="game-container">
<!-- MAIN MENU -->
<div id="menu" class="overlay-screen">
<div id="startScreen">
<div class="start-left">
<h1>ESCAPE FROM<br>TEACHER</h1>
<p style="font-size: 12px; color: #aaa;">Dein Rekord: <span id="localHighscore" style="color:yellow">0</span></p>
<input type="text" id="playerName" placeholder="NAME (4 ZEICHEN)" maxlength="15" style="text-transform:uppercase;">
<button id="startBtn" onclick="startSoloGame()" disabled style="opacity: 0.5; cursor: not-allowed;">SOLO STARTEN</button>
<button id="coopBtn" onclick="showCoopMenu()" disabled style="opacity: 0.5; cursor: not-allowed;">CO-OP SPIELEN</button>
<div class="info-box">
<div class="info-title">SCHUL-NEWS</div>
<p>
• Der Lehrer ist hinter dir her!<br>
• Spring über Hindernisse.<br>
• Sammle Power-Ups für Vorteile!
</p>
</div>
<div class="info-box">
<div class="info-title">STEUERUNG</div>
<p>
PC: <strong>Leertaste</strong> (Springen), <strong>WASD/Pfeile</strong> (Bewegen)<br>
Handy: <strong>Bildschirm-Buttons</strong>
</p>
</div>
<div class="legal-bar">
<button class="legal-btn" onclick="showLeaderboard()">🏆 TOP 10</button>
<button class="legal-btn" onclick="showMyCodes()">🔑 MEINE CODES</button>
<button class="legal-btn" onclick="showSettings()">⚙️ EINSTELLUNGEN</button>
</div>
<div class="legal-bar" style="margin-top: 10px;">
<button class="legal-btn" onclick="showImpressum()">📄 IMPRESSUM</button>
<button class="legal-btn" onclick="showDatenschutz()">🔒 DATENSCHUTZ</button>
</div>
</div>
<div class="start-right">
<div class="hall-of-fame-box">
<h3>🏆 TOP SCHÜLER</h3>
<div id="startLeaderboardList">Lade...</div>
</div>
</div>
</div>
</div>
<!-- CO-OP MENU -->
<div id="coopMenu" class="overlay-screen hidden">
<div class="center-box">
<h1>CO-OP MODUS</h1>
<button id="createRoomBtn" class="big-btn" onclick="createRoom()" disabled style="opacity: 0.5; cursor: not-allowed;">RAUM ERSTELLEN</button>
<div style="margin: 20px 0;">- ODER -</div>
<input type="text" id="joinRoomCode" placeholder="RAUM-CODE" maxlength="6" style="text-transform:uppercase;">
<input type="text" id="teamNameJoin" placeholder="TEAM-NAME" maxlength="15">
<button id="joinRoomBtn" onclick="joinRoom()" disabled style="opacity: 0.5; cursor: not-allowed;">RAUM BEITRETEN</button>
<button class="back-btn" onclick="showMainMenu()">← ZURÜCK</button>
</div>
</div>
<!-- SETTINGS MENU -->
<div id="settingsMenu" class="overlay-screen hidden">
<div class="center-box">
<h1>EINSTELLUNGEN</h1>
<div class="settings-group">
<div class="setting-item">
<label>MUSIK LAUTSTÄRKE:</label>
<input type="range" id="musicVolume" min="0" max="100" value="70">
<span id="musicValue">70%</span>
</div>
<div class="setting-item">
<label>SFX LAUTSTÄRKE:</label>
<input type="range" id="sfxVolume" min="0" max="100" value="70">
<span id="sfxValue">70%</span>
</div>
</div>
<button class="back-btn" onclick="showMainMenu()">← ZURÜCK</button>
</div>
</div>
<!-- LEADERBOARD MENU -->
<div id="leaderboardMenu" class="overlay-screen hidden">
<div class="center-box">
<h1>🏆 TOP 10 LEADERBOARD</h1>
<div id="leaderboardList" class="leaderboard-box">
Lade Leaderboard...
</div>
<button class="back-btn" onclick="showMainMenu()">← ZURÜCK</button>
</div>
</div>
<!-- MY CODES MENU -->
<div id="myCodesMenu" class="overlay-screen hidden">
<div class="center-box">
<h1>🔑 MEINE HIGHSCORE-CODES</h1>
<div id="myCodesList" class="leaderboard-box" style="max-height: 500px;">
Keine Codes gespeichert.
</div>
<button class="back-btn" onclick="showMainMenu()">← ZURÜCK</button>
</div>
</div>
<!-- IMPRESSUM MENU -->
<div id="impressumMenu" class="overlay-screen hidden">
<div class="center-box" style="max-width: 800px;">
<h1>📄 IMPRESSUM & CREDITS</h1>
<div class="leaderboard-box" style="max-height: 500px; overflow-y: auto; text-align: left; font-family: sans-serif; font-size: 13px; line-height: 1.6; background: #333; color: #fff;">
<h3 style="color: #fc0; margin-top: 0;">Projektleitung & Code:</h3>
<p>Sebastian Unterschütz<br>
Göltzschtalblick 16<br>
08236 Ellefeld<br>
<strong>Kontakt:</strong> sebastian@unterschuetz.de</p>
<h3 style="color: #fc0; margin-top: 20px;">🎵 Musik & Sound Design:</h3>
<p>Max Eisel</p>
<h3 style="color: #fc0; margin-top: 20px;">💻 Quellcode:</h3>
<p><a href="https://git.zb-server.de/ZB-Server/EscapeFromTeacher" target="_blank" style="color: #fc0;">git.zb-server.de/ZB-Server/EscapeFromTeacher</a></p>
<h3 style="color: #fc0; margin-top: 20px;">⚖️ Lizenzhinweis:</h3>
<p style="background: rgba(255,204,0,0.1); padding: 10px; border-left: 3px solid #fc0;">
Dies ist ein <strong>Schulprojekt</strong>.<br>
Kommerzielle Nutzung und Veränderung des Quellcodes sind ausdrücklich untersagt.<br>
Alle Rechte liegen bei den Urhebern.
</p>
</div>
<button class="back-btn" onclick="showMainMenu()">← ZURÜCK</button>
</div>
</div>
<!-- DATENSCHUTZ MENU -->
<div id="datenschutzMenu" class="overlay-screen hidden">
<div class="center-box" style="max-width: 800px;">
<h1>🔒 DATENSCHUTZERKLÄRUNG</h1>
<div class="leaderboard-box" style="max-height: 500px; overflow-y: auto; text-align: left; font-family: sans-serif; font-size: 13px; line-height: 1.6; background: #333; color: #fff;">
<h3 style="color: #fc0; margin-top: 0;">1. Datenschutz auf einen Blick</h3>
<p><strong>Allgemeine Hinweise:</strong> Die folgenden Hinweise geben einen einfachen Überblick darüber, was mit Ihren personenbezogenen Daten passiert, wenn Sie diese Website besuchen.</p>
<h3 style="color: #fc0; margin-top: 20px;">2. Verantwortlicher</h3>
<p>Verantwortlich für die Datenverarbeitung auf dieser Website ist:<br>
<strong>Sebastian Unterschütz</strong><br>
Göltzschtalblick 16, 08236 Ellefeld<br>
E-Mail: sebastian@unterschuetz.de<br>
(Schulprojekt im Rahmen der IT232)</p>
<h3 style="color: #fc0; margin-top: 20px;">3. Hosting (Hetzner)</h3>
<p>Wir hosten die Inhalte unserer Website bei folgendem Anbieter:<br>
<strong>Hetzner Online GmbH</strong><br>
Industriestr. 25, 91710 Gunzenhausen, Deutschland</p>
<p><strong>Serverstandort:</strong> Deutschland (ausschließlich).<br>
Wir haben mit dem Anbieter einen Vertrag zur Auftragsverarbeitung (AVV) geschlossen, der die Einhaltung der DSGVO gewährleistet.</p>
<h3 style="color: #fc0; margin-top: 20px;">4. Datenerfassung auf dieser Website</h3>
<h4 style="color: #fc0; margin-top: 15px;">Server-Log-Dateien</h4>
<p>Der Provider der Seiten (Hetzner) erhebt und speichert automatisch Informationen in so genannten Server-Log-Dateien (Browser, OS, Referrer, Hostname, Uhrzeit, IP-Adresse).<br>
<strong>Rechtsgrundlage:</strong> Art. 6 Abs. 1 lit. f DSGVO (Berechtigtes Interesse an technischer Fehlerfreiheit und Sicherheit). Die Daten werden nach spätestens 14 Tagen gelöscht.</p>
<h4 style="color: #fc0; margin-top: 15px;">Spielstände & Highscores</h4>
<p>Wenn Sie einen Highscore eintragen, speichern wir:</p>
<ul style="margin-left: 20px;">
<li>Gewählter Name (Pseudonym empfohlen!)</li>
<li>Punktestand und Zeitstempel</li>
<li>Eindeutiger Player-Code (generiert)</li>
<li>Proof-Code (kryptografischer Hash zur Verifizierung des Scores)</li>
</ul>
<p>Diese Daten dienen der Darstellung der Bestenliste und der Verifikation Ihrer Highscores.</p>
<h4 style="color: #fc0; margin-top: 15px;">Lokale Speicherung (LocalStorage)</h4>
<p>Das Spiel speichert folgende Daten lokal in Ihrem Browser:</p>
<ul style="margin-left: 20px;">
<li>Einstellungen (Audio-Lautstärke)</li>
<li>Ihr Spielername</li>
<li>Ihr Player-Code</li>
<li>Ihre erreichten Highscore-Codes mit Proof-Codes</li>
<li>Lokaler Highscore-Rekord</li>
</ul>
<p>Diese Daten verbleiben <strong>ausschließlich auf Ihrem Gerät</strong> und werden nicht an uns übertragen. Sie können diese Daten jederzeit über die Browser-Einstellungen löschen.</p>
<p style="background: rgba(255,204,0,0.1); padding: 10px; border-left: 3px solid #fc0; margin-top: 15px;">
<strong>Wichtig:</strong> Wir setzen <strong>keine Tracking-Cookies</strong> oder Analyse-Tools ein. Es erfolgt keine Weitergabe Ihrer Daten an Dritte (außer technisch notwendig über Hetzner als Hosting-Provider).
</p>
<h3 style="color: #fc0; margin-top: 20px;">5. Ihre Rechte</h3>
<p>Sie haben jederzeit das Recht auf Auskunft, Berichtigung und Löschung Ihrer Daten. Wenden Sie sich dazu an den Verantwortlichen im Impressum.<br>
Um Ihre lokal gespeicherten Highscore-Codes zu löschen, nutzen Sie die Funktion im Menü <strong>"🔑 MEINE CODES"</strong> oder löschen Sie den Browser-LocalStorage.</p>
</div>
<button class="back-btn" onclick="showMainMenu()">← ZURÜCK</button>
</div>
</div>
<!-- LOBBY SCREEN (CO-OP WAITING ROOM) -->
<div id="lobbyScreen" class="overlay-screen hidden">
<div class="center-box">
<h1>LOBBY</h1>
<div id="lobbyContent" style="display: flex; gap: 20px; width: 100%; justify-content: center; align-items: flex-start;">
<div style="flex: 1; max-width: 400px;">
<p style="font-size: 14px; color: #aaa; margin-bottom: 10px;">Spieler im Raum:</p>
<div id="lobbyPlayerList" style="background: rgba(0,0,0,0.5); border: 2px solid #666; padding: 15px; min-height: 100px; font-family: sans-serif; font-size: 14px;">
<div style="color: #888;">Warte auf Spieler...</div>
</div>
</div>
<div style="flex: 1; max-width: 300px;">
<p style="font-size: 14px; color: #aaa; margin-bottom: 10px;">Raum-Code:</p>
<div style="background: rgba(0,0,0,0.6); border: 4px solid #ffcc00; padding: 20px; font-size: 32px; color: #ffcc00; letter-spacing: 4px; text-align: center;">
<span id="lobbyRoomCode">XXXXX</span>
</div>
</div>
</div>
<div id="lobbyTeamNameBox" class="hidden" style="margin: 20px 0; width: 100%; max-width: 400px;">
<p style="font-size: 14px; color: #aaa; margin-bottom: 10px;">Team-Name (nur Host):</p>
<input type="text" id="lobbyTeamName" placeholder="TEAM-NAME EINGEBEN" maxlength="15" style="text-transform:uppercase; width: 100%; padding: 10px; font-size: 16px;">
<p id="currentTeamName" style="font-size: 12px; color: #ffcc00; margin-top: 5px;">Aktuell: <span id="teamNameDisplay">Nicht gesetzt</span></p>
</div>
<div id="lobbyHostControls" class="hidden" style="margin: 20px 0;">
<button class="big-btn" onclick="startGameFromLobby()" style="background: #00cc00;">SPIEL STARTEN</button>
</div>
<p id="lobbyStatus" style="font-size: 12px; color: #ffcc00; margin: 20px 0;">Warte auf Host...</p>
<button class="back-btn" onclick="leaveLobby()">← LOBBY VERLASSEN</button>
</div>
</div>
<!-- GAME OVER SCREEN -->
<div id="gameOverScreen" class="overlay-screen hidden">
<div class="center-box">
<h1>ERWISCHT!</h1>
<p style="font-size: 18px; margin: 20px 0;">
Dein Score: <span id="finalScore" style="color:yellow; font-size: 24px;">0</span>
</p>
<div id="gameOverLeaderboardList" class="leaderboard-box" style="margin: 20px 0;">
Lade Leaderboard...
</div>
<button class="big-btn" onclick="restartGame()" style="background: #ff4444; margin-top: 20px;">ERNEUT VERSUCHEN</button>
</div>
</div>
<!-- LOADING SCREEN -->
<div id="loading" class="loading-screen">
<div class="spinner"></div>
<p>Lade Escape From Teacher...</p>
</div>
</div>
<!-- WASM Execution -->
<script>
// Cache-Busting für JavaScript-Dateien (wird beim Build aktualisiert)
const BUILD_VERSION = 1767643088942;
document.write('<script src="wasm_exec.js?v=' + BUILD_VERSION + '"><\/script>');
document.write('<script src="game.js?v=' + BUILD_VERSION + '"><\/script>');
</script>
</body>
</html>