Initial commit - Kinderspiele
This commit is contained in:
@@ -0,0 +1,273 @@
|
||||
<!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>Autorennen - KinderWelt</title>
|
||||
<style>
|
||||
* { margin: 0; padding: 0; box-sizing: border-box; user-select: none; }
|
||||
body {
|
||||
background: linear-gradient(135deg, #1a472a 0%, #0f2918 100%);
|
||||
min-height: 100vh; display: flex; flex-direction: column; align-items: center;
|
||||
font-family: 'Comic Sans MS', cursive, sans-serif; padding: 15px;
|
||||
}
|
||||
h1 { color: white; margin-bottom: 10px; font-size: 24px; }
|
||||
.track-container {
|
||||
background: #2d3748; border-radius: 15px; padding: 15px;
|
||||
box-shadow: 0 10px 30px rgba(0,0,0,0.5); margin: 15px 0;
|
||||
}
|
||||
.track {
|
||||
width: 320px; height: 60px; background: linear-gradient(90deg, #4a5568 0%, #718096 50%, #4a5568 100%);
|
||||
border-radius: 10px; margin: 10px 0; position: relative;
|
||||
border: 3px solid #e2e8f0; overflow: hidden;
|
||||
}
|
||||
.track::before {
|
||||
content: ''; position: absolute; top: 50%; left: 0; right: 0;
|
||||
height: 4px; background: repeating-linear-gradient(90deg, #fff 0px, #fff 20px, transparent 20px, transparent 40px);
|
||||
transform: translateY(-50%);
|
||||
}
|
||||
.finish-line {
|
||||
position: absolute; right: 10px; top: 0; bottom: 0; width: 8px;
|
||||
background: repeating-linear-gradient(180deg, #fff 0px, #fff 10px, #000 10px, #000 20px);
|
||||
}
|
||||
.car {
|
||||
position: absolute; left: 10px; top: 50%; transform: translateY(-50%);
|
||||
font-size: 40px; transition: left 0.5s ease-out;
|
||||
filter: drop-shadow(2px 2px 4px rgba(0,0,0,0.5));
|
||||
}
|
||||
.car.moving { animation: bounce 0.3s ease-in-out; }
|
||||
@keyframes bounce {
|
||||
0%, 100% { transform: translateY(-50%) scale(1); }
|
||||
50% { transform: translateY(-60%) scale(1.1); }
|
||||
}
|
||||
|
||||
.dice-container {
|
||||
perspective: 1000px; margin: 20px 0;
|
||||
}
|
||||
.dice {
|
||||
width: 80px; height: 80px; position: relative;
|
||||
transform-style: preserve-3d; cursor: pointer;
|
||||
}
|
||||
.dice.rolling { animation: rollDice 0.8s ease-out; }
|
||||
@keyframes rollDice {
|
||||
0% { transform: rotateX(0) rotateY(0) rotateZ(0); }
|
||||
100% { transform: rotateX(720deg) rotateY(720deg) rotateZ(360deg); }
|
||||
}
|
||||
.face {
|
||||
position: absolute; width: 80px; height: 80px;
|
||||
background: white; border: 2px solid #333; border-radius: 12px;
|
||||
display: flex; justify-content: center; align-items: center;
|
||||
font-size: 40px; font-weight: bold;
|
||||
}
|
||||
.face-1 { transform: rotateY(0deg) translateZ(40px); }
|
||||
.face-2 { transform: rotateY(90deg) translateZ(40px); }
|
||||
.face-3 { transform: rotateY(180deg) translateZ(40px); }
|
||||
.face-4 { transform: rotateY(-90deg) translateZ(40px); }
|
||||
.face-5 { transform: rotateX(90deg) translateZ(40px); }
|
||||
.face-6 { transform: rotateX(-90deg) translateZ(40px); }
|
||||
|
||||
.dot-grid { display: grid; gap: 5px; }
|
||||
.dot-grid.col-2 { grid-template-columns: 1fr 1fr; }
|
||||
.dot { width: 12px; height: 12px; background: #333; border-radius: 50%; }
|
||||
|
||||
.status { color: white; font-size: 20px; margin: 15px 0; text-align: center; }
|
||||
.turn-indicator {
|
||||
background: rgba(255,255,255,0.2); padding: 10px 20px; border-radius: 20px;
|
||||
color: white; margin: 10px 0; font-size: 18px;
|
||||
}
|
||||
.turn-indicator .player { font-weight: bold; }
|
||||
.turn-indicator .player.red { color: #ff6b6b; }
|
||||
.turn-indicator .player.blue { color: #4dabf7; }
|
||||
|
||||
.controls { display: flex; gap: 15px; margin-top: 20px; flex-wrap: wrap; justify-content: center; }
|
||||
.btn {
|
||||
background: white; border: none; border-radius: 10px; padding: 12px 25px;
|
||||
font-size: 16px; cursor: pointer; font-family: inherit; font-weight: bold;
|
||||
}
|
||||
.btn-roll { background: #4ade80; color: white; font-size: 18px; padding: 15px 40px; }
|
||||
.btn-roll:disabled { opacity: 0.5; cursor: not-allowed; }
|
||||
.btn-back { background: #ff6b6b; color: white; text-decoration: none; }
|
||||
|
||||
.winner {
|
||||
position: fixed; top: 50%; left: 50%; transform: translate(-50%, -50%);
|
||||
background: white; padding: 30px 50px; border-radius: 20px;
|
||||
text-align: center; display: none; z-index: 100;
|
||||
box-shadow: 0 10px 50px rgba(0,0,0,0.5);
|
||||
}
|
||||
.winner h2 { color: #333; margin-bottom: 15px; }
|
||||
.winner-emoji { font-size: 60px; }
|
||||
|
||||
.instructions { color: #aaa; text-align: center; margin: 10px 0; font-size: 14px; }
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<h1>🏎️ Autorennen</h1>
|
||||
|
||||
<p class="instructions">Würfle und bewege dein Auto! Wer zuerst im Ziel ist, gewinnt!</p>
|
||||
|
||||
<div class="turn-indicator" id="turnIndicator">
|
||||
<span class="player red">🔴 Rot</span> ist dran!
|
||||
</div>
|
||||
|
||||
<div class="track-container">
|
||||
<div class="track">
|
||||
<div class="finish-line"></div>
|
||||
<div class="car" id="car1">🔴</div>
|
||||
</div>
|
||||
<div class="track">
|
||||
<div class="finish-line"></div>
|
||||
<div class="car" id="car2">🔵</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="status" id="status">Klicke auf den Würfel!</div>
|
||||
|
||||
<div class="dice-container">
|
||||
<div class="dice" id="dice" onclick="roll()">
|
||||
<div class="face face-1"><div class="dot-grid"><div class="dot"></div></div></div>
|
||||
<div class="face face-2"><div class="dot-grid col-2"><div class="dot"></div><div class="dot"></div></div></div>
|
||||
<div class="face face-3"><div class="dot-grid col-2"><div class="dot"></div><div class="dot"></div><div class="dot"></div></div></div>
|
||||
<div class="face face-4"><div class="dot-grid col-2"><div class="dot"></div><div class="dot"></div><div class="dot"></div><div class="dot"></div></div></div>
|
||||
<div class="face face-5"><div class="dot-grid col-2"><div class="dot"></div><div class="dot"></div><div class="dot"></div><div class="dot"></div><div class="dot"></div></div></div>
|
||||
<div class="face face-6"><div class="dot-grid col-2"><div class="dot"></div><div class="dot"></div><div class="dot"></div><div class="dot"></div><div class="dot"></div><div class="dot"></div></div></div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="controls">
|
||||
<button class="btn btn-roll" id="rollBtn" onclick="roll()">🎲 Würfeln</button>
|
||||
<button class="btn" onclick="resetGame()">🔄 Neustart</button>
|
||||
<a href="../index.html" class="btn btn-back">⬅️ Zurück</a>
|
||||
</div>
|
||||
|
||||
<div class="winner" id="winner">
|
||||
<h2>🎉 Gewinner! 🎉</h2>
|
||||
<div class="winner-emoji" id="winnerEmoji"></div>
|
||||
<button class="btn btn-roll" onclick="resetGame()" style="margin-top: 20px">🔄 Nochmal</button>
|
||||
</div>
|
||||
|
||||
<script>
|
||||
const TRACK_LENGTH = 280; // Pixel bis zum Ziel
|
||||
const STEPS_TO_FINISH = 20; // 20 Felder bis zum Ziel
|
||||
|
||||
let positions = [0, 0]; // Position der Autos (in Schritten)
|
||||
let currentPlayer = 0; // 0 = Rot, 1 = Blau
|
||||
let rolling = false;
|
||||
let gameEnded = false;
|
||||
|
||||
const cars = [document.getElementById('car1'), document.getElementById('car2')];
|
||||
const dice = document.getElementById('dice');
|
||||
const status = document.getElementById('status');
|
||||
const turnIndicator = document.getElementById('turnIndicator');
|
||||
|
||||
const rotations = {
|
||||
1: 'rotateX(0deg) rotateY(0deg)',
|
||||
2: 'rotateX(0deg) rotateY(-90deg)',
|
||||
3: 'rotateX(0deg) rotateY(180deg)',
|
||||
4: 'rotateX(0deg) rotateY(90deg)',
|
||||
5: 'rotateX(-90deg) rotateY(0deg)',
|
||||
6: 'rotateX(90deg) rotateY(0deg)'
|
||||
};
|
||||
|
||||
function roll() {
|
||||
if (rolling || gameEnded) return;
|
||||
rolling = true;
|
||||
|
||||
// Animation
|
||||
dice.classList.add('rolling');
|
||||
|
||||
// Zufällige Zahl
|
||||
const result = Math.floor(Math.random() * 6) + 1;
|
||||
|
||||
setTimeout(() => {
|
||||
dice.classList.remove('rolling');
|
||||
dice.style.transform = rotations[result];
|
||||
|
||||
// Auto bewegen
|
||||
moveCar(currentPlayer, result);
|
||||
|
||||
setTimeout(() => {
|
||||
rolling = false;
|
||||
}, 500);
|
||||
|
||||
}, 800);
|
||||
}
|
||||
|
||||
function moveCar(player, steps) {
|
||||
const car = cars[player];
|
||||
car.classList.add('moving');
|
||||
|
||||
positions[player] += steps;
|
||||
|
||||
// Position berechnen (in Pixel)
|
||||
const pixelPos = Math.min(positions[player] / STEPS_TO_FINISH * TRACK_LENGTH, TRACK_LENGTH);
|
||||
car.style.left = (10 + pixelPos) + 'px';
|
||||
|
||||
// Status aktualisieren
|
||||
const playerName = player === 0 ? '🔴 Rot' : '🔵 Blau';
|
||||
status.textContent = playerName + ' würfelt ' + steps + '!';
|
||||
|
||||
// TTS
|
||||
if ('speechSynthesis' in window) {
|
||||
const utterance = new SpeechSynthesisUtterance(playerName.replace('🔴', 'Rot').replace('🔵', 'Blau') + ' würfelt ' + steps);
|
||||
utterance.lang = 'de-DE';
|
||||
speechSynthesis.speak(utterance);
|
||||
}
|
||||
|
||||
setTimeout(() => {
|
||||
car.classList.remove('moving');
|
||||
|
||||
// Prüfen ob gewonnen
|
||||
if (positions[player] >= STEPS_TO_FINISH) {
|
||||
endGame(player);
|
||||
} else {
|
||||
// Nächster Spieler
|
||||
switchPlayer();
|
||||
}
|
||||
}, 500);
|
||||
}
|
||||
|
||||
function switchPlayer() {
|
||||
currentPlayer = currentPlayer === 0 ? 1 : 0;
|
||||
|
||||
if (currentPlayer === 0) {
|
||||
turnIndicator.innerHTML = '<span class="player red">🔴 Rot</span> ist dran!';
|
||||
} else {
|
||||
turnIndicator.innerHTML = '<span class="player blue">🔵 Blau</span> ist dran!';
|
||||
}
|
||||
}
|
||||
|
||||
function endGame(winner) {
|
||||
gameEnded = true;
|
||||
const winnerEmoji = winner === 0 ? '🔴' : '🔵';
|
||||
const winnerName = winner === 0 ? 'Rot' : 'Blau';
|
||||
|
||||
document.getElementById('winnerEmoji').textContent = winnerEmoji + ' ' + winnerName + ' gewinnt!';
|
||||
document.getElementById('winner').style.display = 'block';
|
||||
|
||||
if ('speechSynthesis' in window) {
|
||||
const utterance = new SpeechSynthesisUtterance(winnerName + ' gewinnt das Rennen!');
|
||||
utterance.lang = 'de-DE';
|
||||
speechSynthesis.speak(utterance);
|
||||
}
|
||||
}
|
||||
|
||||
function resetGame() {
|
||||
positions = [0, 0];
|
||||
currentPlayer = 0;
|
||||
gameEnded = false;
|
||||
rolling = false;
|
||||
|
||||
cars.forEach(car => {
|
||||
car.style.left = '10px';
|
||||
car.classList.remove('moving');
|
||||
});
|
||||
|
||||
dice.style.transform = rotations[1];
|
||||
status.textContent = 'Klicke auf den Würfel!';
|
||||
turnIndicator.innerHTML = '<span class="player red">🔴 Rot</span> ist dran!';
|
||||
|
||||
document.getElementById('winner').style.display = 'none';
|
||||
}
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
Reference in New Issue
Block a user