Files
2026-04-26 09:44:19 +02:00

210 lines
8.1 KiB
HTML

<!DOCTYPE html>
<html lang="de">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0, user-scalable=no">
<title>Simon Says - KinderWelt</title>
<style>
* { margin: 0; padding: 0; box-sizing: border-box; user-select: none; }
body {
background: linear-gradient(135deg, #1a1a2e 0%, #16213e 100%);
min-height: 100vh; display: flex; flex-direction: column; align-items: center;
font-family: 'Comic Sans MS', cursive, sans-serif; padding: 20px;
}
h1 { color: white; margin-bottom: 10px; font-size: 28px; }
.score { color: #4ade80; font-size: 20px; margin-bottom: 20px; }
.game-board {
display: grid; grid-template-columns: 1fr 1fr; gap: 10px;
width: 300px; height: 300px; margin: 20px 0;
}
.color-btn {
border: none; border-radius: 20px; cursor: pointer;
opacity: 0.7; transition: all 0.1s;
}
.color-btn.active { opacity: 1; transform: scale(0.95); box-shadow: 0 0 30px currentColor; }
.color-btn:active { transform: scale(0.9); }
.green { background: #22c55e; }
.red { background: #ef4444; }
.yellow { background: #eab308; }
.blue { background: #3b82f6; }
.center-btn {
position: absolute; width: 80px; height: 80px;
background: #1a1a2e; border: 4px solid white; border-radius: 50%;
color: white; font-size: 14px; cursor: pointer;
display: flex; align-items: center; justify-content: center;
}
.game-area { position: relative; }
.status { color: white; font-size: 24px; margin: 20px 0; min-height: 40px; }
.controls { display: flex; gap: 15px; margin-top: 20px; }
.btn {
background: white; border: none; border-radius: 10px; padding: 15px 30px;
font-size: 18px; cursor: pointer; font-family: inherit; font-weight: bold;
}
.btn-back { background: #ff6b6b; color: white; text-decoration: none; }
.btn-start { background: #4ade80; color: white; }
.highscore { color: #feca57; margin-top: 10px; }
</style>
</head>
<body>
<h1>🎵 Simon Says</h1>
<div class="score">Level: <span id="level">0</span></div>
<div class="highscore">Rekord: <span id="highscore">0</span></div>
<div class="game-area">
<div class="game-board">
<button class="color-btn green" data-color="0" onclick="playerClick(0)"></button>
<button class="color-btn red" data-color="1" onclick="playerClick(1)"></button>
<button class="color-btn yellow" data-color="2" onclick="playerClick(2)"></button>
<button class="color-btn blue" data-color="3" onclick="playerClick(3)"></button>
</div>
</div>
<div class="status" id="status">Drücke Start!</div>
<div class="controls">
<button class="btn btn-start" id="startBtn" onclick="startGame()">▶️ Start</button>
<a href="../index.html" class="btn btn-back">⬅️ Zurück</a>
</div>
<script>
const colors = [
{ name: 'green', sound: 523.25 }, // C5
{ name: 'red', sound: 659.25 }, // E5
{ name: 'yellow', sound: 783.99 }, // G5
{ name: 'blue', sound: 987.77 } // B5
];
let sequence = [];
let playerSequence = [];
let level = 0;
let highscore = localStorage.getItem('simon_highscore') || 0;
let gameActive = false;
let audioCtx = null;
document.getElementById('highscore').textContent = highscore;
function initAudio() {
if (!audioCtx) {
audioCtx = new (window.AudioContext || window.webkitAudioContext)();
}
}
function playTone(freq, duration = 300) {
if (!audioCtx) return;
const osc = audioCtx.createOscillator();
const gain = audioCtx.createGain();
osc.connect(gain);
gain.connect(audioCtx.destination);
osc.frequency.value = freq;
gain.gain.setValueAtTime(0.3, audioCtx.currentTime);
gain.gain.exponentialRampToValueAtTime(0.01, audioCtx.currentTime + duration / 1000);
osc.start();
osc.stop(audioCtx.currentTime + duration / 1000);
}
function flashColor(colorIndex, duration = 400) {
const btn = document.querySelector(`[data-color="${colorIndex}"]`);
btn.classList.add('active');
playTone(colors[colorIndex].sound);
setTimeout(() => btn.classList.remove('active'), duration);
}
function startGame() {
initAudio();
sequence = [];
playerSequence = [];
level = 0;
gameActive = true;
document.getElementById('level').textContent = level;
document.getElementById('status').textContent = 'Schau genau hin!';
document.getElementById('startBtn').textContent = '🔄 Neustart';
setTimeout(nextRound, 1000);
}
function nextRound() {
playerSequence = [];
level++;
document.getElementById('level').textContent = level;
document.getElementById('status').textContent = `Level ${level} - Beobachte!`;
sequence.push(Math.floor(Math.random() * 4));
let i = 0;
const playSequence = () => {
if (i < sequence.length) {
flashColor(sequence[i], 500);
i++;
setTimeout(playSequence, 700);
} else {
document.getElementById('status').textContent = 'Dein Zug!';
}
};
setTimeout(playSequence, 500);
}
function playerClick(color) {
if (!gameActive) {
flashColor(color, 200);
return;
}
flashColor(color, 300);
playerSequence.push(color);
const currentIndex = playerSequence.length - 1;
if (playerSequence[currentIndex] !== sequence[currentIndex]) {
// Falsch
gameOver();
return;
}
if (playerSequence.length === sequence.length) {
// Richtig!
document.getElementById('status').textContent = '🎉 Super!';
setTimeout(nextRound, 1000);
}
}
function gameOver() {
gameActive = false;
document.getElementById('status').textContent = `💥 Game Over! Level ${level}`;
// Fehler-Ton
if (audioCtx) {
const osc = audioCtx.createOscillator();
const gain = audioCtx.createGain();
osc.connect(gain);
gain.connect(audioCtx.destination);
osc.frequency.value = 150;
gain.gain.setValueAtTime(0.5, audioCtx.currentTime);
gain.gain.exponentialRampToValueAtTime(0.01, audioCtx.currentTime + 0.5);
osc.start();
osc.stop(audioCtx.currentTime + 0.5);
}
if (level > highscore) {
highscore = level;
localStorage.setItem('simon_highscore', highscore);
document.getElementById('highscore').textContent = highscore;
document.getElementById('status').textContent = `🏆 Neuer Rekord! Level ${level}`;
}
}
// Tastatur-Steuerung
document.addEventListener('keydown', (e) => {
switch(e.key) {
case 'ArrowUp': playerClick(0); break;
case 'ArrowRight': playerClick(1); break;
case 'ArrowDown': playerClick(2); break;
case 'ArrowLeft': playerClick(3); break;
case ' ': startGame(); break;
}
});
</script>
</body>
</html>