Initial commit - Kinderspiele
This commit is contained in:
@@ -0,0 +1,424 @@
|
||||
<!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>Halli Galli - KinderWelt</title>
|
||||
<style>
|
||||
* { margin: 0; padding: 0; box-sizing: border-box; user-select: none; }
|
||||
body {
|
||||
background: linear-gradient(135deg, #667eea 0%, #764ba2 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: 5px; font-size: 24px; }
|
||||
|
||||
.age-hint {
|
||||
color: #FEF3C7; font-size: 14px; margin-bottom: 10px; text-align: center;
|
||||
}
|
||||
|
||||
.difficulty-select {
|
||||
display: flex; gap: 8px; margin: 10px 0; flex-wrap: wrap; justify-content: center;
|
||||
}
|
||||
.diff-btn {
|
||||
background: rgba(255,255,255,0.2); border: 2px solid white; color: white;
|
||||
padding: 8px 15px; border-radius: 20px; cursor: pointer; font-family: inherit;
|
||||
font-size: 13px; transition: all 0.2s;
|
||||
}
|
||||
.diff-btn.active {
|
||||
background: white; color: #667eea; font-weight: bold;
|
||||
transform: scale(1.05);
|
||||
}
|
||||
.diff-btn:hover { background: rgba(255,255,255,0.4); }
|
||||
|
||||
.diff-desc {
|
||||
color: #FEF3C7; font-size: 12px; text-align: center; margin: 5px 0; max-width: 350px;
|
||||
min-height: 30px;
|
||||
}
|
||||
|
||||
.game-area {
|
||||
display: flex; gap: 20px; margin: 15px 0; flex-wrap: wrap; justify-content: center;
|
||||
}
|
||||
|
||||
.card-display {
|
||||
width: 130px; height: 180px; background: white; border-radius: 15px;
|
||||
display: flex; flex-direction: column; align-items: center; justify-content: center;
|
||||
box-shadow: 0 10px 30px rgba(0,0,0,0.3); position: relative; border: 4px solid #333;
|
||||
transition: all 0.3s;
|
||||
}
|
||||
.card-display.match {
|
||||
animation: pulse-match 0.5s ease-in-out;
|
||||
border-color: #FFD700;
|
||||
box-shadow: 0 0 30px #FFD700;
|
||||
}
|
||||
@keyframes pulse-match {
|
||||
0%, 100% { transform: scale(1); }
|
||||
50% { transform: scale(1.05); }
|
||||
}
|
||||
|
||||
.card-emoji { font-size: 60px; }
|
||||
.card-number {
|
||||
font-size: 36px; font-weight: bold; color: #333;
|
||||
margin-top: 5px;
|
||||
}
|
||||
.card-count {
|
||||
position: absolute; bottom: 10px; font-size: 12px; color: #666; font-weight: bold;
|
||||
}
|
||||
.player-name {
|
||||
position: absolute; top: 10px; font-size: 11px; color: #999; font-weight: bold;
|
||||
}
|
||||
|
||||
.big-hint {
|
||||
position: absolute; top: -40px; left: 50%; transform: translateX(-50%);
|
||||
background: #FFD700; color: #333; padding: 5px 15px; border-radius: 20px;
|
||||
font-size: 14px; font-weight: bold; display: none; animation: bounce 0.5s infinite;
|
||||
}
|
||||
@keyframes bounce {
|
||||
0%, 100% { transform: translateX(-50%) translateY(0); }
|
||||
50% { transform: translateX(-50%) translateY(-5px); }
|
||||
}
|
||||
|
||||
.bell-area {
|
||||
width: 160px; height: 160px; background: linear-gradient(135deg, #FFD700, #FFA500);
|
||||
border-radius: 50%; display: flex; flex-direction: column; align-items: center; justify-content: center;
|
||||
cursor: pointer; box-shadow: 0 10px 30px rgba(0,0,0,0.4);
|
||||
border: 8px solid #FF8C00; transition: all 0.1s; position: relative;
|
||||
}
|
||||
.bell-area:active { transform: scale(0.95); }
|
||||
.bell { font-size: 80px; }
|
||||
.bell.ringing { animation: ring 0.3s ease-in-out; }
|
||||
@keyframes ring {
|
||||
0%, 100% { transform: rotate(0deg); }
|
||||
25% { transform: rotate(-15deg); }
|
||||
75% { transform: rotate(15deg); }
|
||||
}
|
||||
.bell-hint {
|
||||
position: absolute; bottom: 15px; font-size: 11px; color: #333; font-weight: bold;
|
||||
}
|
||||
|
||||
.score-board {
|
||||
display: flex; gap: 30px; margin: 10px 0; color: white; font-size: 16px;
|
||||
}
|
||||
.score-item { text-align: center; }
|
||||
.score-value { font-size: 28px; font-weight: bold; color: #feca57; }
|
||||
|
||||
.status {
|
||||
color: white; font-size: 18px; margin: 10px 0; text-align: center;
|
||||
min-height: 50px; font-weight: bold;
|
||||
}
|
||||
|
||||
.fruit-counter {
|
||||
display: flex; gap: 10px; margin: 10px 0; flex-wrap: wrap; justify-content: center;
|
||||
}
|
||||
.fruit-box {
|
||||
background: rgba(255,255,255,0.2); padding: 8px 12px; border-radius: 10px;
|
||||
color: white; font-size: 13px; text-align: center; min-width: 70px;
|
||||
}
|
||||
.fruit-box.highlight {
|
||||
background: #FFD700; color: #333; transform: scale(1.1);
|
||||
box-shadow: 0 0 15px rgba(255,215,0,0.5);
|
||||
}
|
||||
.fruit-count { font-size: 20px; 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: 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);
|
||||
}
|
||||
.game-over h2 { margin-bottom: 15px; }
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<h1>🔔 Halli Galli</h1>
|
||||
<div class="age-hint">👶 Kindermodus: Große Zahlen, visuelle Hilfen, mehr Zeit</div>
|
||||
|
||||
<div class="difficulty-select" id="diffSelect">
|
||||
<button class="diff-btn active" onclick="setDifficulty('baby')">👶 Baby (5 J.)</button>
|
||||
<button class="diff-btn" onclick="setDifficulty('easy')">🟢 Einfach</button>
|
||||
<button class="diff-btn" onclick="setDifficulty('medium')">🟡 Mittel</button>
|
||||
<button class="diff-btn" onclick="setDifficulty('hard')">🔴 Schwer</button>
|
||||
</div>
|
||||
<div class="diff-desc" id="diffDesc">Visuelle Hilfen + 4 Sekunden Zeit zum Reagieren</div>
|
||||
|
||||
<div class="score-board">
|
||||
<div class="score-item">
|
||||
<div>Deine Karten</div>
|
||||
<div class="score-value" id="playerCards">20</div>
|
||||
</div>
|
||||
<div class="score-item">
|
||||
<div>Computer</div>
|
||||
<div class="score-value" id="botCards">20</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="game-area">
|
||||
<div class="card-display" id="playerCard">
|
||||
<div class="big-hint" id="playerHint">🔔 KLINGELN!</div>
|
||||
<div class="player-name">DU</div>
|
||||
<div class="card-emoji" id="playerEmoji">❓</div>
|
||||
<div class="card-number" id="playerNum"></div>
|
||||
<div class="card-count" id="playerCount">20 Karten</div>
|
||||
</div>
|
||||
|
||||
<div class="bell-area" id="bell" onclick="ringBell()">
|
||||
<div class="bell">🔔</div>
|
||||
<div class="bell-hint" id="bellHint">Klick mich!</div>
|
||||
</div>
|
||||
|
||||
<div class="card-display" id="botCard">
|
||||
<div class="player-name">COMPUTER</div>
|
||||
<div class="card-emoji" id="botEmoji">❓</div>
|
||||
<div class="card-number" id="botNum"></div>
|
||||
<div class="card-count" id="botCount">20 Karten</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="status" id="status">Wähle den Schwierigkeitsgrad für deine Tochter! 👧</div>
|
||||
|
||||
<div class="fruit-counter" id="fruitCounter">
|
||||
<div class="fruit-box" id="appleBox">
|
||||
<div>🍎</div>
|
||||
<div class="fruit-count" id="appleCount">0</div>
|
||||
</div>
|
||||
<div class="fruit-box" id="bananaBox">
|
||||
<div>🍌</div>
|
||||
<div class="fruit-count" id="bananaCount">0</div>
|
||||
</div>
|
||||
<div class="fruit-box" id="grapeBox">
|
||||
<div>🍇</div>
|
||||
<div class="fruit-count" id="grapeCount">0</div>
|
||||
</div>
|
||||
<div class="fruit-box" id="strawberryBox">
|
||||
<div>🍓</div>
|
||||
<div class="fruit-count" id="strawberryCount">0</div>
|
||||
</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>
|
||||
|
||||
<div class="game-over" id="gameOver">
|
||||
<h2 id="winnerText">🎉 Gewonnen!</h2>
|
||||
<button class="btn btn-start" onclick="resetGame()">🔄 Nochmal</button>
|
||||
</div>
|
||||
|
||||
<script>
|
||||
const FRUITS = ['🍎', '🍌', '🍇', '🍓'];
|
||||
const DIFFICULTY = {
|
||||
baby: { time: 4000, showHint: true, showCounter: true, desc: '👶 Baby: 4 Sekunden + große Hilfen' },
|
||||
easy: { time: 2500, showHint: true, showCounter: true, desc: '🟢 Einfach: 2.5 Sekunden + Hilfen' },
|
||||
medium: { time: 1500, showHint: false, showCounter: true, desc: '🟡 Mittel: 1.5 Sekunden + Zähler' },
|
||||
hard: { time: 800, showHint: false, showCounter: false, desc: '🔴 Schwer: 0.8 Sekunden, alles selbst!' }
|
||||
};
|
||||
|
||||
let difficulty = 'baby';
|
||||
let playerDeck = [], botDeck = [];
|
||||
let playerCard = null, botCard = null;
|
||||
let gameRunning = false, canRing = false;
|
||||
let botTimer = null;
|
||||
|
||||
function setDifficulty(diff) {
|
||||
difficulty = diff;
|
||||
document.querySelectorAll('.diff-btn').forEach(b => b.classList.remove('active'));
|
||||
event.target.classList.add('active');
|
||||
document.getElementById('diffDesc').textContent = DIFFICULTY[diff].desc;
|
||||
}
|
||||
|
||||
function createDeck() {
|
||||
const deck = [];
|
||||
FRUITS.forEach(fruit => {
|
||||
for (let i = 1; i <= 5; i++) deck.push({ fruit, num: i });
|
||||
});
|
||||
// Doppelte Menge für 40 Karten insgesamt
|
||||
return shuffle([...deck, ...deck]);
|
||||
}
|
||||
|
||||
function shuffle(a) {
|
||||
for (let i = a.length - 1; i > 0; i--) {
|
||||
const j = Math.floor(Math.random() * (i + 1));
|
||||
[a[i], a[j]] = [a[j], a[i]];
|
||||
}
|
||||
return a;
|
||||
}
|
||||
|
||||
function startGame() {
|
||||
const deck = createDeck();
|
||||
playerDeck = deck.slice(0, 20);
|
||||
botDeck = deck.slice(20);
|
||||
gameRunning = true; canRing = false;
|
||||
|
||||
document.getElementById('startBtn').style.display = 'none';
|
||||
document.getElementById('diffSelect').style.display = 'none';
|
||||
document.getElementById('diffDesc').style.display = 'none';
|
||||
document.getElementById('fruitCounter').style.display =
|
||||
DIFFICULTY[difficulty].showCounter ? 'flex' : 'none';
|
||||
|
||||
updateDisplay();
|
||||
nextTurn();
|
||||
}
|
||||
|
||||
function nextTurn() {
|
||||
if (!gameRunning) return;
|
||||
if (playerDeck.length === 0) { endGame(false); return; }
|
||||
if (botDeck.length === 0) { endGame(true); return; }
|
||||
|
||||
// Verstecke Hinweise
|
||||
document.getElementById('playerHint').style.display = 'none';
|
||||
document.getElementById('bellHint').style.display = 'none';
|
||||
document.querySelectorAll('.fruit-box').forEach(b => b.classList.remove('highlight'));
|
||||
document.querySelectorAll('.card-display').forEach(c => c.classList.remove('match'));
|
||||
|
||||
playerCard = playerDeck.shift();
|
||||
botCard = botDeck.shift();
|
||||
|
||||
updateDisplay();
|
||||
updateCounters();
|
||||
|
||||
const counts = { '🍎': 0, '🍌': 0, '🍇': 0, '🍓': 0 };
|
||||
if (playerCard) counts[playerCard.fruit] += playerCard.num;
|
||||
if (botCard) counts[botCard.fruit] += botCard.num;
|
||||
|
||||
const hasFive = Object.values(counts).includes(5);
|
||||
|
||||
if (hasFive) {
|
||||
canRing = true;
|
||||
document.getElementById('status').textContent = '🔔 FÜNF! Schnell klingeln!';
|
||||
document.getElementById('status').style.color = '#FFD700';
|
||||
|
||||
// Visuelle Hilfen für Kinder
|
||||
if (DIFFICULTY[difficulty].showHint) {
|
||||
document.getElementById('playerHint').style.display = 'block';
|
||||
document.getElementById('bellHint').style.display = 'block';
|
||||
document.getElementById('playerCard').classList.add('match');
|
||||
document.getElementById('botCard').classList.add('match');
|
||||
|
||||
// Highlight richtige Frucht
|
||||
for (let [fruit, count] of Object.entries(counts)) {
|
||||
if (count === 5) {
|
||||
const boxId = fruit === '🍎' ? 'appleBox' :
|
||||
fruit === '🍌' ? 'bananaBox' :
|
||||
fruit === '🍇' ? 'grapeBox' : 'strawberryBox';
|
||||
document.getElementById(boxId).classList.add('highlight');
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Bot reagiert
|
||||
botTimer = setTimeout(() => {
|
||||
if (gameRunning && canRing) botRing();
|
||||
}, DIFFICULTY[difficulty].time);
|
||||
} else {
|
||||
canRing = false;
|
||||
document.getElementById('status').textContent = 'Keine 5 gleichen... Nächste Karte!';
|
||||
document.getElementById('status').style.color = 'white';
|
||||
setTimeout(nextTurn, 1500);
|
||||
}
|
||||
}
|
||||
|
||||
function updateCounters() {
|
||||
const counts = { '🍎': 0, '🍌': 0, '🍇': 0, '🍓': 0 };
|
||||
if (playerCard) counts[playerCard.fruit] += playerCard.num;
|
||||
if (botCard) counts[botCard.fruit] += botCard.num;
|
||||
|
||||
document.getElementById('appleCount').textContent = counts['🍎'];
|
||||
document.getElementById('bananaCount').textContent = counts['🍌'];
|
||||
document.getElementById('grapeCount').textContent = counts['🍇'];
|
||||
document.getElementById('strawberryCount').textContent = counts['🍓'];
|
||||
}
|
||||
|
||||
function updateDisplay() {
|
||||
document.getElementById('playerCards').textContent = playerDeck.length;
|
||||
document.getElementById('botCards').textContent = botDeck.length;
|
||||
document.getElementById('playerCount').textContent = (playerDeck.length + 1) + ' Karten';
|
||||
document.getElementById('botCount').textContent = (botDeck.length + 1) + ' Karten';
|
||||
|
||||
if (playerCard) {
|
||||
document.getElementById('playerEmoji').textContent = playerCard.fruit;
|
||||
document.getElementById('playerNum').textContent = playerCard.num;
|
||||
}
|
||||
if (botCard) {
|
||||
document.getElementById('botEmoji').textContent = botCard.fruit;
|
||||
document.getElementById('botNum').textContent = botCard.num;
|
||||
}
|
||||
}
|
||||
|
||||
function ringBell() {
|
||||
if (!canRing || !gameRunning) {
|
||||
// Falsch geklingelt - Strafe!
|
||||
if (gameRunning) {
|
||||
document.getElementById('status').textContent = '❌ Zu früh! Computer bekommt deine Karten!';
|
||||
botDeck.push(...playerDeck.splice(0, Math.min(3, playerDeck.length)));
|
||||
updateDisplay();
|
||||
setTimeout(nextTurn, 2000);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
clearTimeout(botTimer);
|
||||
canRing = false;
|
||||
|
||||
document.querySelector('.bell').classList.add('ringing');
|
||||
setTimeout(() => document.querySelector('.bell').classList.remove('ringing'), 300);
|
||||
|
||||
// Gewinner bekommt alle Karten
|
||||
const wonCards = [playerCard, botCard, ...playerDeck.splice(0, 2), ...botDeck.splice(0, 2)];
|
||||
playerDeck.push(...wonCards.filter(c => c));
|
||||
|
||||
document.getElementById('status').textContent = '🎉 Super! Du hast ' + wonCards.length + ' Karten gewonnen!';
|
||||
updateDisplay();
|
||||
|
||||
setTimeout(nextTurn, 2000);
|
||||
}
|
||||
|
||||
function botRing() {
|
||||
if (!canRing || !gameRunning) return;
|
||||
canRing = false;
|
||||
|
||||
document.querySelector('.bell').classList.add('ringing');
|
||||
setTimeout(() => document.querySelector('.bell').classList.remove('ringing'), 300);
|
||||
|
||||
const wonCards = [playerCard, botCard, ...playerDeck.splice(0, 2), ...botDeck.splice(0, 2)];
|
||||
botDeck.push(...wonCards.filter(c => c));
|
||||
|
||||
document.getElementById('status').textContent = '🤖 Computer war schneller!';
|
||||
updateDisplay();
|
||||
|
||||
setTimeout(nextTurn, 2000);
|
||||
}
|
||||
|
||||
function endGame(playerWon) {
|
||||
gameRunning = false;
|
||||
document.getElementById('winnerText').innerHTML = playerWon ?
|
||||
'🎉 Du hast gewonnen!' : '🤖 Computer gewinnt!';
|
||||
document.getElementById('gameOver').style.display = 'block';
|
||||
}
|
||||
|
||||
function resetGame() {
|
||||
document.getElementById('gameOver').style.display = 'none';
|
||||
document.getElementById('startBtn').style.display = 'block';
|
||||
document.getElementById('diffSelect').style.display = 'flex';
|
||||
document.getElementById('diffDesc').style.display = 'block';
|
||||
document.getElementById('fruitCounter').style.display = 'none';
|
||||
document.getElementById('status').textContent = 'Wähle den Schwierigkeitsgrad!';
|
||||
document.getElementById('status').style.color = 'white';
|
||||
|
||||
playerCard = null; botCard = null;
|
||||
document.getElementById('playerEmoji').textContent = '❓';
|
||||
document.getElementById('playerNum').textContent = '';
|
||||
document.getElementById('botEmoji').textContent = '❓';
|
||||
document.getElementById('botNum').textContent = '';
|
||||
updateDisplay();
|
||||
}
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
Reference in New Issue
Block a user