Initial commit - Kinderspiele
This commit is contained in:
@@ -0,0 +1,272 @@
|
||||
<!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>Zielscheibe - KinderWelt</title>
|
||||
<style>
|
||||
* { margin: 0; padding: 0; box-sizing: border-box; user-select: none; }
|
||||
body {
|
||||
background: linear-gradient(135deg, #1e3c72 0%, #2a5298 100%);
|
||||
min-height: 100vh; display: flex; flex-direction: column; align-items: center;
|
||||
font-family: 'Comic Sans MS', cursive, sans-serif; padding: 20px; overflow: hidden;
|
||||
}
|
||||
h1 { color: white; margin-bottom: 10px; font-size: 26px; }
|
||||
.score-board {
|
||||
display: flex; gap: 30px; margin-bottom: 15px; color: white; font-size: 18px;
|
||||
}
|
||||
.score-item { text-align: center; }
|
||||
.score-value { font-size: 32px; font-weight: bold; color: #feca57; }
|
||||
.game-container {
|
||||
position: relative; width: 350px; height: 350px;
|
||||
background: rgba(255,255,255,0.1); border-radius: 20px;
|
||||
overflow: hidden; cursor: crosshair;
|
||||
}
|
||||
.target {
|
||||
position: absolute; border-radius: 50%; cursor: pointer;
|
||||
animation: appear 0.3s ease-out;
|
||||
}
|
||||
@keyframes appear {
|
||||
from { transform: scale(0); }
|
||||
to { transform: scale(1); }
|
||||
}
|
||||
.target.hit { animation: hit 0.3s ease-out forwards; }
|
||||
@keyframes hit {
|
||||
to { transform: scale(1.5); opacity: 0; }
|
||||
}
|
||||
/* Ringe der Zielscheibe */
|
||||
.ring-1 { width: 60px; height: 60px; background: radial-gradient(circle, #ff6b6b 30%, transparent 30%); }
|
||||
.ring-2 { width: 80px; height: 80px; background: radial-gradient(circle, #ff6b6b 23%, #feca57 23%, #feca57 38%, transparent 38%); }
|
||||
.ring-3 { width: 100px; height: 100px; background: radial-gradient(circle, #ff6b6b 18%, #feca57 18%, #feca57 30%, #4ade80 30%, #4ade80 45%, transparent 45%); }
|
||||
.ring-4 { width: 120px; height: 120px; background: radial-gradient(circle, #ff6b6b 15%, #feca57 15%, #feca57 25%, #4ade80 25%, #4ade80 38%, #3b82f6 38%, #3b82f6 50%, transparent 50%); }
|
||||
.ring-5 { width: 140px; height: 140px; background: radial-gradient(circle, #ff6b6b 13%, #feca57 13%, #feca57 21%, #4ade80 21%, #4ade80 33%, #3b82f6 33%, #3b82f6 43%, #fff 43%, #fff 50%, transparent 50%); }
|
||||
|
||||
.hit-text {
|
||||
position: absolute; font-weight: bold; font-size: 24px;
|
||||
animation: floatUp 1s ease-out forwards; pointer-events: none;
|
||||
}
|
||||
@keyframes floatUp {
|
||||
0% { transform: translateY(0) scale(1); opacity: 1; }
|
||||
100% { transform: translateY(-50px) scale(1.5); opacity: 0; }
|
||||
}
|
||||
.hit-10 { color: #ff6b6b; }
|
||||
.hit-8 { color: #feca57; }
|
||||
.hit-6 { color: #4ade80; }
|
||||
.hit-4 { color: #3b82f6; }
|
||||
.hit-2 { color: #a0aec0; }
|
||||
|
||||
.timer { color: white; font-size: 48px; margin: 10px 0; font-weight: bold; }
|
||||
.controls { display: flex; gap: 15px; margin-top: 15px; }
|
||||
.btn {
|
||||
background: white; border: none; border-radius: 10px; padding: 12px 25px;
|
||||
font-size: 16px; cursor: pointer; font-family: inherit; font-weight: bold;
|
||||
}
|
||||
.btn-start { background: #4ade80; color: white; }
|
||||
.btn-back { background: #ff6b6b; color: white; text-decoration: none; }
|
||||
.game-over {
|
||||
position: absolute; top: 50%; left: 50%; transform: translate(-50%, -50%);
|
||||
background: white; padding: 30px; border-radius: 20px; text-align: center;
|
||||
display: none; z-index: 100;
|
||||
}
|
||||
.game-over h2 { color: #333; margin-bottom: 15px; }
|
||||
.final-score { font-size: 48px; color: #4ade80; font-weight: bold; }
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<h1>🎯 Zielscheibe</h1>
|
||||
|
||||
<div class="score-board">
|
||||
<div class="score-item">
|
||||
<div>Punkte</div>
|
||||
<div class="score-value" id="score">0</div>
|
||||
</div>
|
||||
<div class="score-item">
|
||||
<div>Treffer</div>
|
||||
<div class="score-value" id="hits">0</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="timer" id="timer">30</div>
|
||||
|
||||
<div class="game-container" id="gameContainer">
|
||||
<div class="game-over" id="gameOver">
|
||||
<h2>🎉 Zeit abgelaufen!</h2>
|
||||
<div class="final-score" id="finalScore">0</div>
|
||||
<div style="margin-top: 15px; color: #666">Punkte</div>
|
||||
<button class="btn btn-start" onclick="startGame()" style="margin-top: 20px">🔄 Nochmal</button>
|
||||
</div>
|
||||
</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>
|
||||
let score = 0;
|
||||
let hits = 0;
|
||||
let timeLeft = 30;
|
||||
let gameActive = false;
|
||||
let timerInterval = null;
|
||||
let targetInterval = null;
|
||||
let highscore = localStorage.getItem('zielscheibe_highscore') || 0;
|
||||
|
||||
const container = document.getElementById('gameContainer');
|
||||
const scoreEl = document.getElementById('score');
|
||||
const hitsEl = document.getElementById('hits');
|
||||
const timerEl = document.getElementById('timer');
|
||||
const gameOverEl = document.getElementById('gameOver');
|
||||
const finalScoreEl = document.getElementById('finalScore');
|
||||
|
||||
function startGame() {
|
||||
score = 0;
|
||||
hits = 0;
|
||||
timeLeft = 30;
|
||||
gameActive = true;
|
||||
|
||||
scoreEl.textContent = '0';
|
||||
hitsEl.textContent = '0';
|
||||
timerEl.textContent = '30';
|
||||
gameOverEl.style.display = 'none';
|
||||
document.getElementById('startBtn').style.display = 'none';
|
||||
|
||||
// Container leeren
|
||||
container.innerHTML = '';
|
||||
container.appendChild(gameOverEl);
|
||||
|
||||
// Erste Zielscheibe
|
||||
spawnTarget();
|
||||
|
||||
// Timer
|
||||
timerInterval = setInterval(() => {
|
||||
timeLeft--;
|
||||
timerEl.textContent = timeLeft;
|
||||
|
||||
if (timeLeft <= 10) {
|
||||
timerEl.style.color = '#ff6b6b';
|
||||
}
|
||||
|
||||
if (timeLeft <= 0) {
|
||||
endGame();
|
||||
}
|
||||
}, 1000);
|
||||
|
||||
// Neue Zielscheiben automatisch
|
||||
targetInterval = setInterval(() => {
|
||||
if (gameActive && document.querySelectorAll('.target').length < 3) {
|
||||
spawnTarget();
|
||||
}
|
||||
}, 1500);
|
||||
}
|
||||
|
||||
function spawnTarget() {
|
||||
const target = document.createElement('div');
|
||||
const ringSize = Math.floor(Math.random() * 5) + 1;
|
||||
target.className = 'target ring-' + ringSize;
|
||||
|
||||
// Zufällige Position (nicht zu nah am Rand)
|
||||
const maxX = container.offsetWidth - 150;
|
||||
const maxY = container.offsetHeight - 150;
|
||||
const x = 20 + Math.random() * maxX;
|
||||
const y = 20 + Math.random() * maxY;
|
||||
|
||||
target.style.left = x + 'px';
|
||||
target.style.top = y + 'px';
|
||||
|
||||
// Punkte basierend auf Ring
|
||||
const points = ringSize === 1 ? 10 : ringSize === 2 ? 8 : ringSize === 3 ? 6 : ringSize === 4 ? 4 : 2;
|
||||
|
||||
target.onclick = function(e) {
|
||||
e.stopPropagation();
|
||||
if (!gameActive) return;
|
||||
|
||||
hitTarget(target, points, e.clientX, e.clientY);
|
||||
};
|
||||
|
||||
// Automatisch entfernen nach 3 Sekunden
|
||||
setTimeout(() => {
|
||||
if (target.parentNode) {
|
||||
target.remove();
|
||||
}
|
||||
}, 3000);
|
||||
|
||||
container.appendChild(target);
|
||||
}
|
||||
|
||||
function hitTarget(target, points, x, y) {
|
||||
score += points;
|
||||
hits++;
|
||||
scoreEl.textContent = score;
|
||||
hitsEl.textContent = hits;
|
||||
|
||||
// Hit-Text anzeigen
|
||||
const hitText = document.createElement('div');
|
||||
hitText.className = 'hit-text hit-' + points;
|
||||
hitText.textContent = '+' + points;
|
||||
hitText.style.left = (target.offsetLeft + target.offsetWidth/2 - 20) + 'px';
|
||||
hitText.style.top = target.offsetTop + 'px';
|
||||
container.appendChild(hitText);
|
||||
|
||||
setTimeout(() => hitText.remove(), 1000);
|
||||
|
||||
// Animation
|
||||
target.classList.add('hit');
|
||||
|
||||
// Sound via TTS
|
||||
if ('speechSynthesis' in window && points >= 8) {
|
||||
const utterance = new SpeechSynthesisUtterance(points + ' Punkte');
|
||||
utterance.lang = 'de-DE';
|
||||
utterance.rate = 1.2;
|
||||
speechSynthesis.speak(utterance);
|
||||
}
|
||||
|
||||
setTimeout(() => {
|
||||
target.remove();
|
||||
// Neue Zielscheibe sofort
|
||||
if (gameActive) spawnTarget();
|
||||
}, 300);
|
||||
}
|
||||
|
||||
function endGame() {
|
||||
gameActive = false;
|
||||
clearInterval(timerInterval);
|
||||
clearInterval(targetInterval);
|
||||
|
||||
finalScoreEl.textContent = score;
|
||||
gameOverEl.style.display = 'block';
|
||||
timerEl.style.color = 'white';
|
||||
|
||||
// Highscore
|
||||
if (score > highscore) {
|
||||
highscore = score;
|
||||
localStorage.setItem('zielscheibe_highscore', highscore);
|
||||
finalScoreEl.innerHTML = score + '<br><small style="font-size:20px">🏆 Neuer Rekord!</small>';
|
||||
}
|
||||
|
||||
if ('speechSynthesis' in window) {
|
||||
const utterance = new SpeechSynthesisUtterance('Spiel vorbei. Du hast ' + score + ' Punkte erreicht.');
|
||||
utterance.lang = 'de-DE';
|
||||
speechSynthesis.speak(utterance);
|
||||
}
|
||||
}
|
||||
|
||||
// Verfehlte Klicks = -1 Punkt
|
||||
container.addEventListener('click', (e) => {
|
||||
if (!gameActive || e.target.classList.contains('target')) return;
|
||||
|
||||
score = Math.max(0, score - 1);
|
||||
scoreEl.textContent = score;
|
||||
|
||||
// Visuelles Feedback
|
||||
const missText = document.createElement('div');
|
||||
missText.className = 'hit-text';
|
||||
missText.style.color = '#ff6b6b';
|
||||
missText.textContent = '-1';
|
||||
missText.style.left = (e.offsetX - 10) + 'px';
|
||||
missText.style.top = (e.offsetY - 20) + 'px';
|
||||
container.appendChild(missText);
|
||||
setTimeout(() => missText.remove(), 800);
|
||||
});
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
Reference in New Issue
Block a user