Initial commit - Kinderspiele
This commit is contained in:
@@ -0,0 +1,387 @@
|
||||
<!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>Leiterspiel - KinderWelt</title>
|
||||
<style>
|
||||
* { margin: 0; padding: 0; box-sizing: border-box; user-select: none; }
|
||||
body {
|
||||
background: linear-gradient(135deg, #4a5568 0%, #2d3748 100%);
|
||||
min-height: 100vh; display: flex; flex-direction: column; align-items: center;
|
||||
font-family: 'Comic Sans MS', cursive, sans-serif; padding: 10px;
|
||||
}
|
||||
h1 { color: white; margin-bottom: 10px; font-size: 22px; }
|
||||
|
||||
.board-container {
|
||||
background: #8B7355; padding: 10px; border-radius: 15px;
|
||||
box-shadow: 0 10px 30px rgba(0,0,0,0.5);
|
||||
}
|
||||
|
||||
.board {
|
||||
display: grid; grid-template-columns: repeat(10, 30px); gap: 2px;
|
||||
}
|
||||
|
||||
.cell {
|
||||
width: 30px; height: 30px; border-radius: 4px;
|
||||
display: flex; align-items: center; justify-content: center;
|
||||
font-size: 9px; font-weight: bold; position: relative;
|
||||
}
|
||||
|
||||
/* Schachbrett-Muster */
|
||||
.cell:nth-child(even) { background: #F5DEB3; }
|
||||
.cell:nth-child(odd) { background: #DEB887; }
|
||||
|
||||
.cell.start { background: #90EE90 !important; }
|
||||
.cell.finish { background: #FFD700 !important; border: 2px solid #FFA500; }
|
||||
.cell.ladder { background: #87CEEB !important; }
|
||||
.cell.snake { background: #ff9999 !important; }
|
||||
|
||||
.cell-number { position: absolute; top: 2px; left: 2px; font-size: 7px; }
|
||||
|
||||
.piece {
|
||||
width: 16px; height: 16px; border-radius: 50%;
|
||||
position: absolute; border: 1px solid white;
|
||||
box-shadow: 1px 1px 3px rgba(0,0,0,0.5);
|
||||
z-index: 10; font-size: 8px; display: flex; align-items: center; justify-content: center;
|
||||
}
|
||||
.piece.p1 { background: #ff4444; color: white; }
|
||||
.piece.p2 { background: #4444ff; color: white; }
|
||||
|
||||
/* Emoji auf Feldern */
|
||||
.cell-icon { font-size: 14px; }
|
||||
|
||||
/* UI */
|
||||
.turn-indicator {
|
||||
background: rgba(255,255,255,0.2); padding: 10px 20px; border-radius: 20px;
|
||||
color: white; margin: 10px 0; font-size: 16px;
|
||||
}
|
||||
|
||||
.status { color: white; font-size: 14px; margin: 10px 0; text-align: center; max-width: 320px; }
|
||||
|
||||
/* Würfel */
|
||||
.dice-area { margin: 15px 0; }
|
||||
.dice {
|
||||
width: 60px; height: 60px; background: white; border-radius: 10px;
|
||||
display: flex; align-items: center; justify-content: center;
|
||||
font-size: 30px; cursor: pointer; border: 3px solid #333;
|
||||
box-shadow: 0 5px 15px rgba(0,0,0,0.3);
|
||||
}
|
||||
.dice.rolling { animation: shake 0.5s ease-in-out; }
|
||||
@keyframes shake {
|
||||
0%, 100% { transform: rotate(0deg); }
|
||||
25% { transform: rotate(-10deg); }
|
||||
75% { transform: rotate(10deg); }
|
||||
}
|
||||
|
||||
.controls { display: flex; gap: 10px; margin-top: 15px; }
|
||||
.btn {
|
||||
background: white; border: none; border-radius: 10px; padding: 10px 20px;
|
||||
font-size: 14px; cursor: pointer; font-family: inherit; font-weight: bold;
|
||||
}
|
||||
.btn-roll { background: #4ade80; color: white; }
|
||||
.btn-back { background: #ff6b6b; color: white; text-decoration: none; }
|
||||
|
||||
.legend {
|
||||
display: flex; gap: 15px; margin: 10px 0; flex-wrap: wrap; justify-content: center;
|
||||
}
|
||||
.legend-item { display: flex; align-items: center; gap: 5px; color: white; font-size: 12px; }
|
||||
.legend-box { width: 18px; height: 18px; border-radius: 3px; }
|
||||
|
||||
.winner {
|
||||
position: fixed; top: 50%; left: 50%; transform: translate(-50%, -50%);
|
||||
background: white; padding: 30px; border-radius: 20px;
|
||||
text-align: center; display: none; z-index: 100;
|
||||
box-shadow: 0 10px 50px rgba(0,0,0,0.5);
|
||||
}
|
||||
.winner h2 { margin-bottom: 15px; }
|
||||
.winner-emoji { font-size: 40px; }
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<h1>🐍 Leiterspiel 🪜</h1>
|
||||
|
||||
<div class="turn-indicator" id="turnIndicator">
|
||||
🔴 Spieler 1 ist dran!
|
||||
</div>
|
||||
|
||||
<div class="board-container">
|
||||
<div class="board" id="board"></div>
|
||||
</div>
|
||||
|
||||
<div class="legend">
|
||||
<div class="legend-item">
|
||||
<div class="legend-box" style="background:#87CEEB"></div>
|
||||
🪜 Leiter
|
||||
</div>
|
||||
<div class="legend-item">
|
||||
<div class="legend-box" style="background:#ff9999"></div>
|
||||
🐍 Schlange
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="status" id="status">Würfle und klettere hoch! Aber pass auf vor den Schlangen! 🐍</div>
|
||||
|
||||
<div class="dice-area">
|
||||
<div class="dice" id="dice" onclick="roll()">🎲</div>
|
||||
</div>
|
||||
|
||||
<div class="controls">
|
||||
<button class="btn btn-roll" 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="winnerText"></div>
|
||||
<button class="btn btn-roll" onclick="resetGame()" style="margin-top: 15px">🔄 Nochmal</button>
|
||||
</div>
|
||||
|
||||
<script>
|
||||
// Leitern: von -> nach oben
|
||||
const LADDERS = {
|
||||
4: 14, // 4 -> 14
|
||||
9: 31, // 9 -> 31
|
||||
20: 38, // 20 -> 38
|
||||
28: 84, // 28 -> 84
|
||||
40: 59, // 40 -> 59
|
||||
51: 67, // 51 -> 67
|
||||
63: 81, // 63 -> 81
|
||||
71: 91 // 71 -> 91
|
||||
};
|
||||
|
||||
// Schlangen: von -> nach unten
|
||||
const SNAKES = {
|
||||
17: 7, // 17 -> 7
|
||||
54: 34, // 54 -> 34
|
||||
62: 19, // 62 -> 19
|
||||
64: 60, // 64 -> 60
|
||||
87: 24, // 87 -> 24
|
||||
93: 73, // 93 -> 73
|
||||
95: 75, // 95 -> 75
|
||||
99: 78 // 99 -> 78
|
||||
};
|
||||
|
||||
let positions = [1, 1]; // Spieler 1 und 2
|
||||
let currentPlayer = 0; // 0 = Spieler 1, 1 = Spieler 2
|
||||
let rolling = false;
|
||||
let gameEnded = false;
|
||||
|
||||
function initBoard() {
|
||||
const board = document.getElementById('board');
|
||||
board.innerHTML = '';
|
||||
|
||||
// Brett: Zeile 10 (100-91), Zeile 9 (81-90), etc.
|
||||
for (let row = 9; row >= 0; row--) {
|
||||
const isEvenRow = row % 2 === 0;
|
||||
const startNum = row * 10 + 1;
|
||||
const endNum = (row + 1) * 10;
|
||||
|
||||
for (let i = 0; i < 10; i++) {
|
||||
const num = isEvenRow ? startNum + i : endNum - i;
|
||||
|
||||
const cell = document.createElement('div');
|
||||
cell.className = 'cell';
|
||||
cell.dataset.num = num;
|
||||
|
||||
// Start
|
||||
if (num === 1) {
|
||||
cell.classList.add('start');
|
||||
cell.innerHTML = '<span class="cell-icon">🏠</span>';
|
||||
}
|
||||
// Ziel
|
||||
else if (num === 100) {
|
||||
cell.classList.add('finish');
|
||||
cell.innerHTML = '<span class="cell-icon">🏆</span>';
|
||||
}
|
||||
// Leiter
|
||||
else if (LADDERS[num]) {
|
||||
cell.classList.add('ladder');
|
||||
cell.innerHTML = '<span class="cell-icon">🪜</span>';
|
||||
cell.title = 'Nach ' + LADDERS[num];
|
||||
}
|
||||
// Schlange
|
||||
else if (SNAKES[num]) {
|
||||
cell.classList.add('snake');
|
||||
cell.innerHTML = '<span class="cell-icon">🐍</span>';
|
||||
cell.title = 'Nach ' + SNAKES[num];
|
||||
}
|
||||
else {
|
||||
cell.innerHTML = '<span class="cell-number">' + num + '</span>';
|
||||
}
|
||||
|
||||
board.appendChild(cell);
|
||||
}
|
||||
}
|
||||
|
||||
updatePieces();
|
||||
}
|
||||
|
||||
function updatePieces() {
|
||||
// Alte Figuren entfernen
|
||||
document.querySelectorAll('.piece').forEach(p => p.remove());
|
||||
|
||||
// Neue Figuren setzen
|
||||
positions.forEach((pos, idx) => {
|
||||
const cell = document.querySelector(`[data-num="${pos}"]`);
|
||||
if (cell) {
|
||||
const piece = document.createElement('div');
|
||||
piece.className = 'piece p' + (idx + 1);
|
||||
piece.textContent = (idx + 1);
|
||||
|
||||
// Position innerhalb der Zelle
|
||||
if (idx === 0) {
|
||||
piece.style.top = '2px';
|
||||
piece.style.left = '2px';
|
||||
} else {
|
||||
piece.style.bottom = '2px';
|
||||
piece.style.right = '2px';
|
||||
}
|
||||
|
||||
cell.appendChild(piece);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
function roll() {
|
||||
if (rolling || gameEnded) return;
|
||||
rolling = true;
|
||||
|
||||
const dice = document.getElementById('dice');
|
||||
dice.classList.add('rolling');
|
||||
|
||||
// Zufällige Zahlen zeigen während des Rollens
|
||||
let rollInterval = setInterval(() => {
|
||||
dice.textContent = Math.floor(Math.random() * 6) + 1;
|
||||
}, 100);
|
||||
|
||||
setTimeout(() => {
|
||||
clearInterval(rollInterval);
|
||||
dice.classList.remove('rolling');
|
||||
|
||||
const result = Math.floor(Math.random() * 6) + 1;
|
||||
dice.textContent = result;
|
||||
|
||||
movePlayer(result);
|
||||
|
||||
setTimeout(() => {
|
||||
rolling = false;
|
||||
}, 600);
|
||||
|
||||
}, 500);
|
||||
}
|
||||
|
||||
function movePlayer(rollNum) {
|
||||
const playerName = currentPlayer === 0 ? '🔴 Spieler 1' : '🔵 Spieler 2';
|
||||
let currentPos = positions[currentPlayer];
|
||||
let newPos = currentPos + rollNum;
|
||||
|
||||
const status = document.getElementById('status');
|
||||
|
||||
// Über 100?
|
||||
if (newPos > 100) {
|
||||
status.textContent = playerName + ' muss genau auf 100 kommen! Bleibt auf ' + currentPos;
|
||||
speak(playerName + ' bleibt auf ' + currentPos);
|
||||
switchPlayer();
|
||||
return;
|
||||
}
|
||||
|
||||
// Bewegen
|
||||
status.textContent = playerName + ' würfelt ' + rollNum + ' und geht zu Feld ' + newPos;
|
||||
speak(playerName.replace('🔴', '').replace('🔵', '') + ' zieht auf Feld ' + newPos);
|
||||
|
||||
positions[currentPlayer] = newPos;
|
||||
updatePieces();
|
||||
|
||||
// Prüfen auf Leiter oder Schlange
|
||||
setTimeout(() => {
|
||||
checkSpecial(newPos);
|
||||
}, 500);
|
||||
}
|
||||
|
||||
function checkSpecial(pos) {
|
||||
const status = document.getElementById('status');
|
||||
const playerName = currentPlayer === 0 ? '🔴 Spieler 1' : '🔵 Spieler 2';
|
||||
|
||||
// Leiter?
|
||||
if (LADDERS[pos]) {
|
||||
const target = LADDERS[pos];
|
||||
positions[currentPlayer] = target;
|
||||
status.innerHTML = '🎉 ' + playerName + ' findet eine 🪜 Leiter! Hoch zu Feld ' + target + '!';
|
||||
speak('Leiter! Hoch zu Feld ' + target);
|
||||
updatePieces();
|
||||
|
||||
checkWin();
|
||||
}
|
||||
// Schlange?
|
||||
else if (SNAKES[pos]) {
|
||||
const target = SNAKES[pos];
|
||||
positions[currentPlayer] = target;
|
||||
status.innerHTML = '😱 ' + playerName + ' trifft auf eine 🐍 Schlange! Runter zu Feld ' + target + '!';
|
||||
speak('Schlange! Runter zu Feld ' + target);
|
||||
updatePieces();
|
||||
|
||||
checkWin();
|
||||
}
|
||||
// Gewonnen?
|
||||
else if (pos === 100) {
|
||||
checkWin();
|
||||
}
|
||||
else {
|
||||
switchPlayer();
|
||||
}
|
||||
}
|
||||
|
||||
function checkWin() {
|
||||
if (positions[currentPlayer] === 100) {
|
||||
gameEnded = true;
|
||||
const playerName = currentPlayer === 0 ? '🔴 Spieler 1' : '🔵 Spieler 2';
|
||||
|
||||
document.getElementById('winnerText').innerHTML = playerName + '<br><small>hat gewonnen! 🏆</small>';
|
||||
document.getElementById('winner').style.display = 'block';
|
||||
|
||||
speak(playerName + ' hat gewonnen!');
|
||||
} else {
|
||||
switchPlayer();
|
||||
}
|
||||
}
|
||||
|
||||
function switchPlayer() {
|
||||
currentPlayer = currentPlayer === 0 ? 1 : 0;
|
||||
|
||||
const indicator = document.getElementById('turnIndicator');
|
||||
if (currentPlayer === 0) {
|
||||
indicator.innerHTML = '🔴 Spieler 1 ist dran!';
|
||||
} else {
|
||||
indicator.innerHTML = '🔵 Spieler 2 ist dran!';
|
||||
}
|
||||
}
|
||||
|
||||
function resetGame() {
|
||||
positions = [1, 1];
|
||||
currentPlayer = 0;
|
||||
gameEnded = false;
|
||||
rolling = false;
|
||||
|
||||
document.getElementById('dice').textContent = '🎲';
|
||||
document.getElementById('status').textContent = 'Würfle und klettere hoch! Aber pass auf vor den Schlangen! 🐍';
|
||||
document.getElementById('turnIndicator').innerHTML = '🔴 Spieler 1 ist dran!';
|
||||
document.getElementById('winner').style.display = 'none';
|
||||
|
||||
initBoard();
|
||||
}
|
||||
|
||||
function speak(text) {
|
||||
if ('speechSynthesis' in window) {
|
||||
const utterance = new SpeechSynthesisUtterance(text);
|
||||
utterance.lang = 'de-DE';
|
||||
speechSynthesis.speak(utterance);
|
||||
}
|
||||
}
|
||||
|
||||
// Init
|
||||
initBoard();
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
Reference in New Issue
Block a user