Initial commit - Kinderspiele
This commit is contained in:
@@ -0,0 +1,210 @@
|
||||
<!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>
|
||||
Reference in New Issue
Block a user