210 lines
8.1 KiB
HTML
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> |