Private
Public Access
1
0

big refactor
Some checks failed
Dynamic Branch Deploy / build-and-deploy (push) Failing after 48s

This commit is contained in:
Sebastian Unterschütz
2025-11-25 18:11:47 +01:00
parent 6afcd4aa94
commit 732f507547
17 changed files with 1519 additions and 1295 deletions

View File

@@ -4,6 +4,7 @@
<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 the Teacher</title>
<link rel="stylesheet" href="style.css">
</head>
<body>
@@ -22,8 +23,10 @@
</div>
<div id="startScreen">
<div class="start-left">
<h1>ESCAPE THE<br>TEACHER</h1>
<p style="font-size: 12px; color: #aaa;">Dein Rekord: <span id="localHighscore" style="color:yellow">0</span></p>
<button id="startBtn" onclick="startGameClick()">STARTEN</button>
@@ -34,22 +37,22 @@
<p>
• Herr Müller verteilt heute Nachsitzen!<br>
• Spring über Tische und Mülleimer.<br>
Lass dich nicht erwischen!
<strong>Neu:</strong> Ducken (Pfeil Runter) gegen fliegende Schwämme!
</p>
</div>
<div class="info-box">
<div class="info-title">STEUERUNG</div>
<p>
PC: <strong>Leertaste</strong>, <strong>Pfeil Hoch/Runter</strong> oder <strong>Mausklick</strong><br>
Handy: <strong>Tippen</strong> (Springen) oder <strong>Wischen</strong> (Ducken)
PC: <strong>Leertaste/Maus</strong> (Springen), <strong>Pfeil Runter</strong> (Ducken)<br>
Handy: <strong>Tippen</strong> (Springen), <strong>Wischen nach unten</strong> (Ducken)
</p>
</div>
<div class="legal-bar">
<button class="legal-btn" onclick="showMyCodes()" style="color:yellow; border-color:yellow;">★ MEINE CODES</button>
<button class="legal-btn" onclick="openModal('impressum')">Impressum</button>
<button class="legal-btn" onclick="openModal('datenschutz')">Datenschutz</button>
<button class="legal-btn" onclick="showMyCodes()" style="border-color: yellow; color: yellow;">★ MEINE CODES</button>
</div>
</div>
@@ -76,24 +79,28 @@
</div>
</div>
<div id="modal-impressum" class="modal-overlay">
<div class="modal-content">
<button class="close-modal" onclick="closeModal()">X</button>
<h2>Impressum</h2>
<p><strong>Angaben gemäß § 5 TMG:</strong></p>
<p>Max Mustermann<br>Musterschule 1<br>12345 Musterstadt</p>
<p>Kontakt: max@schule.de</p>
<p><em>Schulprojekt. Keine kommerzielle Absicht.</em></p>
</div>
</div>
<div id="modal-codes" class="modal-overlay">
<div class="modal-content">
<button class="close-modal" onclick="closeModal()">X</button>
<h2 style="color:yellow">MEINE BEWEISE</h2>
<div id="codesList" style="font-size: 10px; line-height: 1.8;">
</div>
<p style="margin-top:20px; font-size:9px; color:#888;">Zeige diesen Code dem Lehrer für deinen Preis oder zum Löschen.</p>
<p style="margin-top:20px; font-size:9px; color:#888;">Zeige diesen Code dem Lehrer für deinen Preis oder lösche den Eintrag.</p>
</div>
</div>
<div id="modal-impressum" class="modal-overlay">
<div class="modal-content">
<button class="close-modal" onclick="closeModal()">X</button>
<h2>Impressum</h2>
<p><strong>Angaben gemäß § 5 TMG:</strong></p>
<p>
Sebastian Unterschütz<br>
Göltzschtalblick 16 <br>
08236 Ellefeld
</p>
<p>Kontakt: sebastian@unterschuetz.de</p>
<p><em>Dies ist ein Schulprojekt ohne kommerzielle Absicht.</em></p>
</div>
</div>
@@ -101,81 +108,54 @@
<div class="modal-content">
<button class="close-modal" onclick="closeModal()">X</button>
<h2>Datenschutz</h2>
<p>Wir speichern deinen Namen und Score für die Bestenliste.</p>
<p>Dein persönlicher Highscore wird lokal auf deinem Gerät gespeichert.</p>
<p><strong>1. Allgemeines</strong><br>
Dies ist ein Schulprojekt. Wir speichern so wenig Daten wie möglich.</p>
<p><strong>2. Welche Daten speichern wir?</strong><br>
Wenn du einen Highscore einträgst, speichern wir auf unserem Server:
<ul>
<li>Deinen gewählten Namen</li>
<li>Deinen Punktestand</li>
<li>Einen Zeitstempel</li>
<li>Einen zufälligen "Beweis-Code"</li>
</ul>
</p>
<p><strong>3. Lokale Speicherung (Dein Gerät)</strong><br>
Das Spiel nutzt den "LocalStorage" deines Browsers, um deinen persönlichen Rekord und deine gesammelten Beweis-Codes zu speichern. Diese Daten verlassen dein Gerät nicht, außer du sendest sie aktiv ab.</p>
<p><strong>4. Cookies & Tracking</strong><br>
Wir verwenden <strong>keine</strong> Tracking-Cookies, keine Analyse-Tools (wie Google Analytics) und laden keine Schriftarten von fremden Servern.</p>
<p><strong>5. Deine Rechte</strong><br>
Du kannst deine Einträge jederzeit selbstständig über das Menü "Meine Codes" vom Server löschen.</p>
</div>
</div>
<script src="game.js"></script>
<script src="js/config.js"></script>
<script src="js/state.js"></script>
<script src="js/network.js"></script>
<script src="js/input.js"></script>
<script src="js/logic.js"></script>
<script src="js/render.js"></script>
<script src="js/main.js"></script>
<script>
function openModal(id) { document.getElementById('modal-' + id).style.display = 'flex'; }
function closeModal() { document.querySelectorAll('.modal-overlay').forEach(el => el.style.display = 'none'); }
function openModal(id) {
document.getElementById('modal-' + id).style.display = 'flex';
}
function closeModal() {
const modals = document.querySelectorAll('.modal-overlay');
modals.forEach(el => el.style.display = 'none');
}
// Schließen wenn man daneben klickt
window.onclick = function(event) {
if (event.target.classList.contains('modal-overlay')) closeModal();
}
async function deleteClaim(index, sid, code) {
if(!confirm("Willst du diesen Score wirklich unwiderruflich löschen?")) return;
try {
const res = await fetch('/api/claim/delete', {
method: 'POST',
headers: {'Content-Type': 'application/json'},
body: JSON.stringify({ sessionId: sid, claimCode: code })
});
if (!res.ok) {
alert("Fehler: Konnte nicht löschen (Vielleicht Session abgelaufen?)");
} else {
alert("Erfolgreich gelöscht!");
}
let claims = JSON.parse(localStorage.getItem('escape_claims') || '[]');
claims.splice(index, 1);
localStorage.setItem('escape_claims', JSON.stringify(claims));
showMyCodes();
} catch(e) {
alert("Verbindungsfehler");
if (event.target.classList.contains('modal-overlay')) {
closeModal();
}
}
function showMyCodes() {
openModal('codes');
const listEl = document.getElementById('codesList');
const claims = JSON.parse(localStorage.getItem('escape_claims') || '[]');
if (claims.length === 0) {
listEl.innerHTML = "Noch keine Scores eingetragen.";
return;
}
let html = "";
// Wir gehen rückwärts durch (neueste oben)
// Wir brauchen den Index 'i', um das Element auch aus dem LocalStorage zu löschen
for (let i = claims.length - 1; i >= 0; i--) {
const c = claims[i];
// Fallback, falls alte Einträge noch keine SessionID haben
const btnDisabled = c.sessionId ? "" : "disabled";
const btnStyle = c.sessionId ? "cursor:pointer; color:red;" : "color:gray;";
html += `
<div style="border-bottom:1px solid #444; padding:8px 0; display:flex; justify-content:space-between; align-items:center;">
<div>
<span style="color:white; font-weight:bold;">${c.code}</span>
<span style="color:#ffcc00;">(${c.score} Pkt)</span><br>
<span style="color:#aaa;">${c.name} - ${c.date}</span>
</div>
<button onclick="deleteClaim(${i}, '${c.sessionId}', '${c.code}')"
style="background:transparent; border:1px solid #555; padding:5px; font-size:10px; ${btnStyle}"
${btnDisabled}>
LÖSCHEN
</button>
</div>`;
}
listEl.innerHTML = html;
}
</script>
</body>
</html>