diff --git a/Archive.zip b/Archive.zip new file mode 100644 index 0000000..4f9ca4f Binary files /dev/null and b/Archive.zip differ diff --git a/sys_digger/beschreibung.md b/sys_digger/beschreibung.md new file mode 100644 index 0000000..542d656 --- /dev/null +++ b/sys_digger/beschreibung.md @@ -0,0 +1,33 @@ +# Sys Digger – Spielbeschreibung + +## Was ist Sys Digger? + +Sys Digger ist ein browserbasiertes Reaktionsspiel, das lose auf dem bekannten Arcade-Klassiker **Whac-a-Mole** basiert. Statt Maulwürfe zu treffen, geht es hier jedoch um Chemie und Moleküle: Der Spieler muss ein zentrales Atom davor schützen, zu einem gefährlichen **Cystinstein** heranzuwachsen. + +## Spielprinzip + +Im Zentrum des Bildschirms befindet sich ein Molekül mit mehreren **Ankerpunkten** um sich herum. Von den Rändern des Bildschirms nähern sich fremde Atome und versuchen, an diesen Ankerpunkten anzudocken. Gelingt eine Verbindung, wächst das Molekül ein Stück weiter in Richtung Cystinstein. + +Der Spieler muss dies verhindern – und zwar durch gezieltes Klicken auf den leuchtend roten Ankerpunkt, bevor das anfliegende Atom dort andockt. + +## Steuerung + +- **Mausklick** auf einen rot markierten Ankerpunkt, sobald sich ein Atom nähert. +- Trifft der Klick rechtzeitig, wird die Verbindung blockiert und der Spieler erhält einen **Punkt**. +- Kommt der Klick zu spät oder wird der Ankerpunkt verfehlt, dockt das Atom an. + +## Spielverlauf + +- Je länger das Spiel andauert, desto schneller erscheinen neue Atome – die Schwierigkeit steigt kontinuierlich. +- In der **oberen linken Ecke** befindet sich ein kleines Panel, das den aktuellen Zustand des Cystinsteins zeigt. Mit jeder erfolgreichen Andockung wächst dort ein neues Atom hinzu. +- Wurden **6 Andockungen** nicht verhindert, ist der Cystinstein vollständig gebildet – das Spiel ist verloren. + +## Highscore + +Nach jedem Spiel kann der Spieler seinen Namen eingeben und seinen Punktestand in der **Bestenliste** speichern. Die Top-10-Ergebnisse werden dauerhaft gespeichert und sind beim nächsten Besuch wieder abrufbar. + +Bleibt der Startbildschirm 30 Sekunden unberührt, wechselt das Spiel automatisch in eine **Highscore-Ansicht**, die die aktuelle Bestenliste anzeigt. Ein Klick oder ein Tastendruck bringt den Startbildschirm zurück. + +## Ziel + +So viele Andockversuche wie möglich abwehren, den Highscore knacken – und verhindern, dass der Cystinstein entsteht. diff --git a/thiola-pong/constants.js b/thiola-pong/constants.js new file mode 100644 index 0000000..84564d5 --- /dev/null +++ b/thiola-pong/constants.js @@ -0,0 +1,57 @@ +const PADDLE_W = 12; +const PADDLE_H = 90; +const PADDLE_MARGIN = 42; +const BALL_R = 7; +const BASE_SPEED = 5; +const WIN_SCORE = 5; +const MAX_LEVEL = 3; +const WALL_WIDTH = 32; + +const LEVEL_COVERAGE = [0, 0, 40, 70]; +const LEVEL_CPU_SPEED = [0, 1.6, 3.0, 3.8]; + +const playerGoalMessages = [ + { icon: '🔬', title: 'Steinanalyse rettet Leben', + text: 'Jeder Nierenstein sollte analysiert werden. Nur so kann ein Cystinstein sicher identifiziert werden.' }, + { icon: '🎯', title: 'Früherkennung ist der Schlüssel', + text: 'Je früher Cystinurie erkannt wird, desto besser die Prognose. Die Steinanalyse ist der erste Schritt zur Diagnose.' }, + { icon: '💊', title: 'Thiola senkt das Cystinniveau', + text: 'Thiola (Tiopronin) senkt die Cystinkonzentration im Urin und verhindert die Neubildung von Steinen.' }, + { icon: '🛡️', title: 'Schutz durch konsequente Therapie', + text: 'Unter konsequenter Thiola-Therapie kann die Steinbildungsrate signifikant reduziert werden.' }, + { icon: '✅', title: 'Evidenzbasierter Therapiestandard', + text: 'Tiopronin (Thiola) ist der Goldstandard in der medikamentösen Prävention von Cystinsteinen.' }, + { icon: '🔁', title: 'Rezidivprophylaxe mit Thiola', + text: 'Ohne spezifische Therapie liegt die Rezidivrate bei Cystinsteinen bei bis zu 60%. Thiola kann das verhindern.' }, + { icon: '📋', title: 'Leitliniengerecht handeln', + text: 'Die urologischen Leitlinien empfehlen eine konsequente Steinanalyse als Basis jeder Metaphylaxe.' }, + { icon: '🏆', title: 'Therapieerfolg messbar', + text: 'Unter Thiola-Therapie kann die Cystinausscheidung im Urin kontrolliert und der Therapieerfolg laborchemisch überwacht werden.' }, + { icon: '💎', title: 'Analyse schafft Klarheit', + text: 'Cystinsteine machen nur 1–2% aller Nierensteine aus — ohne Analyse bleiben sie unerkannt.' }, + { icon: '🔑', title: 'Der Schlüssel zur Prävention', + text: 'Steinanalyse → Diagnose → Thiola — dieser Dreiklang schützt Patienten vor neuen Steinen.' }, +]; + +const cpuGoalMessages = [ + { icon: '⚡', title: 'Kolikschmerzen — unerträglich', + text: 'Nierenkoliken gehören zu den stärksten Schmerzen, die ein Mensch erleben kann. Cystinstein-Patienten erleben das immer wieder.' }, + { icon: '🔄', title: 'Rezidive ohne Ende', + text: 'Ohne gezielte Therapie bilden sich Cystinsteine immer wieder neu. Bis zu 60% Rezidivrate — ein Teufelskreis für Betroffene.' }, + { icon: '🏥', title: 'Wiederholte Operationen', + text: 'Viele Cystinurie-Patienten müssen mehrfach operiert werden. Jeder Eingriff belastet die Niere zusätzlich.' }, + { icon: '⏳', title: 'Diagnose oft viel zu spät', + text: 'Ohne Steinanalyse dauert es oft Jahre bis zur richtigen Diagnose. Wertvolle Zeit, in der die Niere Schaden nimmt.' }, + { icon: '🫘', title: 'Nierenfunktion in Gefahr', + text: 'Wiederholte Steinereignisse können zum Verlust der Nierenfunktion führen — besonders bei jungen Patienten.' }, + { icon: '👶', title: 'Junge Patienten betroffen', + text: 'Cystinurie manifestiert sich oft schon im Kindes- und Jugendalter. Betroffene leiden ihr ganzes Leben.' }, + { icon: '🧬', title: 'Genetisch bedingt — lebenslang', + text: 'Cystinurie ist eine autosomal-rezessiv vererbte Erkrankung. Die Steinbildung hört ohne Therapie nie auf.' }, + { icon: '😔', title: 'Lebensqualität massiv eingeschränkt', + text: 'Ständige Angst vor der nächsten Kolik, Krankenhausaufenthalte, OPs — die Lebensqualität sinkt drastisch.' }, + { icon: '❓', title: 'Fehlende Steinanalyse = Blindflug', + text: 'Ohne Steinanalyse wird symptomatisch statt kausal behandelt. Die wahre Ursache bleibt im Dunkeln.' }, + { icon: '📉', title: 'Kosten für das Gesundheitssystem', + text: 'Wiederholte Notaufnahmen, OPs und Krankheitstage — unerkannte Cystinurie verursacht immense Folgekosten.' }, +]; diff --git a/thiola-pong/game.js b/thiola-pong/game.js new file mode 100644 index 0000000..03eb558 --- /dev/null +++ b/thiola-pong/game.js @@ -0,0 +1,451 @@ +(() => { + const canvas = document.getElementById('canvas'); + const ctx = canvas.getContext('2d'); + const W = canvas.width, H = canvas.height; + + // DOM + const overlay = document.getElementById('overlay'); + const startBtnCpu = document.getElementById('start-btn-cpu'); + const startBtnPvp = document.getElementById('start-btn-pvp'); + const hudLevel = document.getElementById('hud-level'); + const hudShield = document.getElementById('hud-shield'); + const hudPScore = document.getElementById('hud-pscore'); + const hudCScore = document.getElementById('hud-cscore'); + const popup = document.getElementById('popup'); + const popupTitle = document.getElementById('popup-title'); + const popupContent = document.getElementById('popup-content'); + const popupSub = document.getElementById('popup-sub'); + const popupBtn = document.getElementById('popup-btn'); + const goalFlash = document.getElementById('goal-flash'); + const flashScore = document.getElementById('flash-score'); + const flashIcon = document.getElementById('flash-icon'); + const flashTitle = document.getElementById('flash-title'); + const flashText = document.getElementById('flash-text'); + + // ─── Game state ─── + let level = 1, playerScore = 0, cpuScore = 0; + let running = false, paused = false; + let gameMode = 'cpu'; // 'cpu' or 'pvp' + + let ballX, ballY, ballVX, ballVY; + let playerY = H/2 - PADDLE_H/2, cpuY = H/2 - PADDLE_H/2; + let cpuSpeed = 1.6; + let coveragePercent = 0, gapTop, gapBottom; + let keyW = false, keyS = false; + let keyUp = false, keyDown = false, mouseY = null; + let particles = [], trails = []; + let glowPhase = 0; + + let playerMsgIndex = 0, cpuMsgIndex = 0; + + // ─── Level config ─── + function getCoverage(lvl) { const v = LEVEL_COVERAGE[lvl]; return v !== undefined ? v : 70; } + function getCpuSpeed(lvl) { const v = LEVEL_CPU_SPEED[lvl]; return v !== undefined ? v : 3.8; } + + // ─── Helpers ─── + function calcGap() { + const openH = H * ((100 - coveragePercent) / 100); + gapTop = (H - openH) / 2; + gapBottom = gapTop + openH; + } + + function resetBall(dir) { + ballX = W / 2; ballY = H / 2; + const angle = (Math.random() * 0.7 - 0.35); + const speed = BASE_SPEED + level * 0.2; + ballVX = speed * dir; + ballVY = speed * Math.sin(angle); + } + + function spawnParticles(x, y, color, count) { + for (let i = 0; i < count; i++) { + particles.push({ x, y, vx: (Math.random()-.5)*7, vy: (Math.random()-.5)*7, life: 1, decay: 0.02+Math.random()*0.03, r: 2+Math.random()*3, color }); + } + } + + function updateHUD() { + hudLevel.textContent = level; + hudShield.textContent = Math.round(coveragePercent); + hudPScore.textContent = playerScore; + hudCScore.textContent = cpuScore; + } + + function startLevel() { + playerScore = 0; cpuScore = 0; + coveragePercent = getCoverage(level); + cpuSpeed = getCpuSpeed(level); + calcGap(); resetBall(1); updateHUD(); + } + + // ─── Score a goal ─── + function scoreGoal(isPlayerGoal) { + if (isPlayerGoal) playerScore++; + else cpuScore++; + updateHUD(); + void hudPScore.offsetHeight; + showGoalFlash(isPlayerGoal); + } + + // ─── Goal flash (edu per goal) ─── + function showGoalFlash(isPlayerGoal) { + paused = true; + + let msg; + if (isPlayerGoal) { + msg = playerGoalMessages[playerMsgIndex % playerGoalMessages.length]; + playerMsgIndex++; + } else { + msg = cpuGoalMessages[cpuMsgIndex % cpuGoalMessages.length]; + cpuMsgIndex++; + } + + flashScore.textContent = `${playerScore} : ${cpuScore}`; + flashIcon.textContent = msg.icon; + flashTitle.textContent = msg.title; + flashText.innerHTML = msg.text; + void goalFlash.offsetHeight; + goalFlash.className = isPlayerGoal ? 'show player-goal' : 'show cpu-goal'; + + function cont(e) { + if (e && e.type === 'keydown') { + const k = e.key; + if (k === 'ArrowUp' || k === 'ArrowDown' || k === 'w' || k === 'W' || k === 's' || k === 'S') return; + } + goalFlash.className = ''; + document.removeEventListener('keydown', cont); + goalFlash.removeEventListener('click', cont); + if (playerScore >= WIN_SCORE) { advanceLevel(); } + else if (cpuScore >= WIN_SCORE) { showGameOver(); } + else { paused = false; resetBall(isPlayerGoal ? -1 : 1); } + } + + setTimeout(() => { + document.addEventListener('keydown', cont); + goalFlash.addEventListener('click', cont); + }, 400); + } + + // ─── Popup helper ─── + function showPopup(title, html, sub, btnText, btnClass, onContinue) { + popupTitle.textContent = title; + popupContent.innerHTML = html; + popupSub.textContent = sub || ''; + popupBtn.textContent = btnText; + popupBtn.className = btnClass || 'game-btn'; + popup.classList.add('show'); + paused = true; + popupBtn.onclick = () => { + popup.classList.remove('show'); + paused = false; + popupBtn.blur(); + if (onContinue) onContinue(); + }; + } + + // ─── Start screen ─── + function showStartScreen() { + running = false; + paused = false; + level = 1; + coveragePercent = 0; + popup.classList.remove('show'); + overlay.classList.remove('hidden'); + } + + // ─── Level transitions ─── + function advanceLevel() { + if (level === 1) { + level = 2; + showPopup('LEVEL 1 GESCHAFFT!', + `
+ Nierensteine treffen auf dein Tor — kannst du sie abwehren?
+ Gewinne 3 Level mit jeweils 5 Punkten Vorsprung.
+ Ab Level 2 schützt Thiola dein Tor!
+