managarten/games/arcade/apps/web/static/games/word_scramble.html
Till JS 9e82e40e16 rename(mana-games): rebrand to Arcade
Rename games/mana-games/ to games/arcade/, update all package names
(@mana-games/* → @arcade/*), appIds, display names, docker-compose
service, root scripts, and documentation.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-29 18:31:37 +02:00

1274 lines
No EOL
45 KiB
HTML

<!DOCTYPE html>
<html lang="de">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Word Scramble</title>
<style>
* {
margin: 0;
padding: 0;
box-sizing: border-box;
}
body {
background: #2a1810;
background-image:
repeating-linear-gradient(45deg, transparent, transparent 35px, rgba(255,255,255,.02) 35px, rgba(255,255,255,.02) 70px),
radial-gradient(ellipse at top, #3d2418, #1a0f08);
color: #fff;
font-family: 'Georgia', serif;
min-height: 100vh;
display: flex;
justify-content: center;
align-items: center;
overflow: hidden;
}
.game-container {
max-width: 800px;
width: 100%;
padding: 20px;
text-align: center;
filter: drop-shadow(0 0 30px rgba(0, 0, 0, 0.5));
min-height: 100vh;
display: flex;
flex-direction: column;
justify-content: center;
}
.header {
margin-bottom: 20px;
background: linear-gradient(135deg, #8b6914, #cdaa3d, #8b6914);
padding: 15px;
border-radius: 15px;
border: 3px solid #5a4012;
box-shadow:
inset 0 2px 4px rgba(255,255,255,0.3),
inset 0 -2px 4px rgba(0,0,0,0.5),
0 5px 10px rgba(0,0,0,0.5);
}
h1 {
font-size: 42px;
margin: 0;
text-shadow:
2px 2px 0px #5a4012,
3px 3px 0px #3d2a0c,
4px 4px 6px rgba(0, 0, 0, 0.8);
letter-spacing: 3px;
font-family: 'Times New Roman', serif;
color: #fff8dc;
}
.game-info {
display: flex;
justify-content: space-around;
align-items: center;
margin-bottom: 20px;
flex-wrap: wrap;
gap: 15px;
min-height: 80px;
}
.info-item {
background: linear-gradient(145deg, #4a3525, #2e1f15);
padding: 15px 25px;
border-radius: 12px;
border: 2px solid #1a0f08;
box-shadow:
inset 0 2px 8px rgba(255,255,255,0.1),
inset 0 -2px 8px rgba(0,0,0,0.8),
0 4px 8px rgba(0,0,0,0.6);
position: relative;
}
.info-item::before {
content: '';
position: absolute;
top: 3px;
left: 3px;
right: 3px;
height: 40%;
background: linear-gradient(180deg, rgba(255,255,255,0.1), transparent);
border-radius: 10px 10px 0 0;
}
.score {
font-size: 24px;
font-weight: bold;
color: #ffd700;
text-shadow: 0 2px 4px rgba(0,0,0,0.8);
}
.timer {
font-size: 24px;
font-weight: bold;
color: #ff6b6b;
text-shadow: 0 2px 4px rgba(0,0,0,0.8);
}
.level {
font-size: 24px;
font-weight: bold;
color: #4ecdc4;
text-shadow: 0 2px 4px rgba(0,0,0,0.8);
}
.category-display {
font-size: 18px;
color: #8b6914;
margin-bottom: 20px;
text-transform: uppercase;
letter-spacing: 2px;
text-shadow: 1px 1px 2px rgba(0,0,0,0.5);
font-family: 'Georgia', serif;
position: absolute;
top: 20px;
left: 50%;
transform: translateX(-50%);
z-index: 2;
background: rgba(244, 229, 194, 0.8);
padding: 5px 20px;
border-radius: 20px;
border: 2px solid #8b7355;
}
.word-container {
background: linear-gradient(145deg, #f4e5c2, #d4c5a2);
padding: 40px;
border-radius: 8px;
margin-bottom: 30px;
box-shadow:
inset 0 2px 4px rgba(255,255,255,0.5),
inset 0 -4px 8px rgba(0,0,0,0.3),
0 8px 16px rgba(0,0,0,0.4);
min-height: 350px;
height: 350px;
display: flex;
flex-direction: column;
justify-content: center;
align-items: center;
border: 3px solid #8b7355;
position: relative;
overflow: hidden;
}
.word-container::before {
content: '';
position: absolute;
top: 0;
left: 0;
right: 0;
bottom: 0;
background-image:
repeating-linear-gradient(0deg, transparent, transparent 30px, rgba(139,115,85,0.1) 30px, rgba(139,115,85,0.1) 31px);
pointer-events: none;
}
.scrambled-word {
font-size: 48px;
letter-spacing: 8px;
font-weight: bold;
text-shadow: 2px 2px 4px rgba(0, 0, 0, 0.5);
color: #2d1810;
z-index: 1;
position: relative;
display: flex;
flex-wrap: wrap;
justify-content: center;
align-items: center;
gap: 10px;
}
.letter {
display: inline-flex;
justify-content: center;
align-items: center;
background: linear-gradient(145deg, #8b7355, #6b5a45);
width: 70px;
height: 70px;
margin: 8px;
border-radius: 8px;
box-shadow:
inset 0 2px 4px rgba(255,255,255,0.2),
inset 0 -2px 4px rgba(0,0,0,0.5),
0 4px 8px rgba(0,0,0,0.3);
border: 2px solid #5a4a3a;
transition: all 0.3s ease;
cursor: pointer;
font-family: 'Georgia', serif;
color: #fff8dc;
text-shadow: 1px 1px 2px rgba(0,0,0,0.5);
position: relative;
font-size: 36px;
font-weight: bold;
}
.letter::before {
content: '';
position: absolute;
top: 2px;
left: 2px;
right: 2px;
height: 40%;
background: linear-gradient(180deg, rgba(255,255,255,0.2), transparent);
border-radius: 6px 6px 0 0;
}
.letter:hover {
transform: translateY(-3px);
box-shadow:
inset 0 2px 4px rgba(255,255,255,0.3),
inset 0 -2px 4px rgba(0,0,0,0.5),
0 6px 12px rgba(0,0,0,0.4);
background: linear-gradient(145deg, #9b8365, #7b6a55);
}
.letter:active {
transform: translateY(-1px);
box-shadow:
inset 0 2px 4px rgba(0,0,0,0.3),
inset 0 -2px 4px rgba(255,255,255,0.1),
0 2px 4px rgba(0,0,0,0.3);
}
.input-container {
margin-bottom: 20px;
min-height: 60px;
display: flex;
justify-content: center;
align-items: center;
}
#guessInput {
padding: 15px 30px;
font-size: 24px;
border: 3px solid #5a4a3a;
border-radius: 8px;
background: linear-gradient(145deg, #f8f0e0, #e8d8c0);
color: #2d1810;
width: 300px;
text-align: center;
outline: none;
transition: all 0.3s ease;
box-shadow:
inset 0 2px 4px rgba(0,0,0,0.1),
inset 0 -2px 4px rgba(255,255,255,0.8),
0 4px 8px rgba(0,0,0,0.3);
font-family: 'Georgia', serif;
font-weight: bold;
}
#guessInput:focus {
box-shadow:
inset 0 2px 6px rgba(0,0,0,0.2),
inset 0 -2px 4px rgba(255,255,255,0.8),
0 4px 12px rgba(0,0,0,0.4),
0 0 20px rgba(212,175,55,0.3);
border-color: #8b6914;
}
.buttons {
display: flex;
justify-content: center;
gap: 15px;
margin-bottom: 20px;
flex-wrap: wrap;
min-height: 60px;
align-items: center;
}
button {
padding: 12px 30px;
font-size: 18px;
border: 3px solid;
border-radius: 8px;
cursor: pointer;
transition: all 0.3s ease;
font-weight: bold;
text-transform: uppercase;
letter-spacing: 1px;
font-family: 'Georgia', serif;
position: relative;
text-shadow: 1px 1px 2px rgba(0,0,0,0.5);
}
button::before {
content: '';
position: absolute;
top: 2px;
left: 2px;
right: 2px;
height: 45%;
background: linear-gradient(180deg, rgba(255,255,255,0.3), transparent);
border-radius: 5px 5px 0 0;
}
button:active {
transform: translateY(2px);
}
.submit-btn {
background: linear-gradient(145deg, #5ac85a, #4aa84a);
color: #fff;
border-color: #2d6b2d;
box-shadow:
inset 0 2px 4px rgba(255,255,255,0.3),
inset 0 -3px 6px rgba(0,0,0,0.4),
0 4px 8px rgba(0,0,0,0.3);
}
.submit-btn:hover {
background: linear-gradient(145deg, #6ad86a, #5ab85a);
box-shadow:
inset 0 2px 4px rgba(255,255,255,0.4),
inset 0 -3px 6px rgba(0,0,0,0.4),
0 6px 12px rgba(0,0,0,0.4);
}
.submit-btn:active {
box-shadow:
inset 0 2px 4px rgba(0,0,0,0.3),
inset 0 -1px 2px rgba(255,255,255,0.2),
0 2px 4px rgba(0,0,0,0.3);
}
.hint-btn {
background: linear-gradient(145deg, #f0ad4e, #d58512);
color: #fff;
border-color: #8b5a00;
box-shadow:
inset 0 2px 4px rgba(255,255,255,0.3),
inset 0 -3px 6px rgba(0,0,0,0.4),
0 4px 8px rgba(0,0,0,0.3);
}
.hint-btn:hover {
background: linear-gradient(145deg, #ffbd5e, #e59522);
box-shadow:
inset 0 2px 4px rgba(255,255,255,0.4),
inset 0 -3px 6px rgba(0,0,0,0.4),
0 6px 12px rgba(0,0,0,0.4);
}
.hint-btn:active {
box-shadow:
inset 0 2px 4px rgba(0,0,0,0.3),
inset 0 -1px 2px rgba(255,255,255,0.2),
0 2px 4px rgba(0,0,0,0.3);
}
.skip-btn {
background: linear-gradient(145deg, #d9534f, #c9302c);
color: #fff;
border-color: #8b211e;
box-shadow:
inset 0 2px 4px rgba(255,255,255,0.3),
inset 0 -3px 6px rgba(0,0,0,0.4),
0 4px 8px rgba(0,0,0,0.3);
}
.skip-btn:hover {
background: linear-gradient(145deg, #e9635f, #d9403c);
box-shadow:
inset 0 2px 4px rgba(255,255,255,0.4),
inset 0 -3px 6px rgba(0,0,0,0.4),
0 6px 12px rgba(0,0,0,0.4);
}
.skip-btn:active {
box-shadow:
inset 0 2px 4px rgba(0,0,0,0.3),
inset 0 -1px 2px rgba(255,255,255,0.2),
0 2px 4px rgba(0,0,0,0.3);
}
.btn-primary {
background: linear-gradient(145deg, #8b6914, #cdaa3d);
color: #fff;
border: 3px solid #5a4012;
box-shadow:
inset 0 2px 4px rgba(255,255,255,0.3),
inset 0 -3px 6px rgba(0,0,0,0.4),
0 4px 8px rgba(0,0,0,0.3);
}
.btn-primary:hover {
background: linear-gradient(145deg, #9b7924, #ddba4d);
box-shadow:
inset 0 2px 4px rgba(255,255,255,0.4),
inset 0 -3px 6px rgba(0,0,0,0.4),
0 6px 12px rgba(0,0,0,0.4);
}
.btn-primary:active {
box-shadow:
inset 0 2px 4px rgba(0,0,0,0.3),
inset 0 -1px 2px rgba(255,255,255,0.2),
0 2px 4px rgba(0,0,0,0.3);
}
.hint-text {
font-size: 18px;
color: #8b6914;
margin-top: 20px;
min-height: 30px;
height: 30px;
font-style: italic;
text-shadow: 1px 1px 2px rgba(0,0,0,0.3);
font-family: 'Georgia', serif;
z-index: 1;
position: relative;
display: flex;
align-items: center;
justify-content: center;
}
.combo-display {
position: absolute;
top: 20px;
right: 20px;
font-size: 32px;
font-weight: bold;
color: #ff6b6b;
opacity: 0;
transition: opacity 0.3s ease;
background: linear-gradient(145deg, #4a3525, #2e1f15);
padding: 10px 20px;
border-radius: 12px;
border: 2px solid #1a0f08;
box-shadow:
inset 0 2px 8px rgba(255,255,255,0.1),
inset 0 -2px 8px rgba(0,0,0,0.8),
0 4px 8px rgba(0,0,0,0.6);
text-shadow: 2px 2px 4px rgba(0,0,0,0.8);
}
.combo-display.active {
opacity: 1;
animation: pulse 0.5s ease;
}
@keyframes pulse {
0%, 100% { transform: scale(1); }
50% { transform: scale(1.1); }
}
.particle {
position: absolute;
pointer-events: none;
opacity: 0;
animation: particleFloat 1s ease-out;
}
@keyframes particleFloat {
0% {
opacity: 1;
transform: translateY(0) scale(1);
}
100% {
opacity: 0;
transform: translateY(-100px) scale(0.5);
}
}
.game-state-content {
text-align: center;
padding: 20px;
z-index: 1;
position: relative;
}
.game-state-content h2 {
font-size: 36px;
margin-bottom: 20px;
color: #8b6914;
text-shadow:
2px 2px 0px #5a4012,
3px 3px 6px rgba(0, 0, 0, 0.8);
font-family: 'Times New Roman', serif;
}
.game-state-content p {
font-size: 20px;
margin-bottom: 30px;
line-height: 1.6;
color: #5a4012;
text-shadow: 1px 1px 2px rgba(0,0,0,0.2);
font-family: 'Georgia', serif;
}
.start-btn, .restart-btn {
background: linear-gradient(145deg, #8b6914, #6b4914);
color: #fff;
padding: 15px 40px;
font-size: 20px;
border: 3px solid #5a4012;
box-shadow:
inset 0 2px 4px rgba(255,255,255,0.3),
inset 0 -3px 6px rgba(0,0,0,0.4),
0 4px 8px rgba(0,0,0,0.3);
cursor: pointer;
font-weight: bold;
text-transform: uppercase;
letter-spacing: 1px;
font-family: 'Georgia', serif;
position: relative;
text-shadow: 1px 1px 2px rgba(0,0,0,0.5);
border-radius: 8px;
margin: 10px;
}
.start-btn:hover, .restart-btn:hover {
background: linear-gradient(145deg, #9b7924, #7b5924);
box-shadow:
inset 0 2px 4px rgba(255,255,255,0.4),
inset 0 -3px 6px rgba(0,0,0,0.4),
0 6px 12px rgba(0,0,0,0.4);
}
.start-btn:active, .restart-btn:active {
transform: translateY(2px);
box-shadow:
inset 0 2px 4px rgba(0,0,0,0.3),
inset 0 -1px 2px rgba(255,255,255,0.2),
0 2px 4px rgba(0,0,0,0.3);
}
.start-btn::before, .restart-btn::before {
content: '';
position: absolute;
top: 2px;
left: 2px;
right: 2px;
height: 45%;
background: linear-gradient(180deg, rgba(255,255,255,0.3), transparent);
border-radius: 5px 5px 0 0;
}
.power-up-display {
position: absolute;
top: 20px;
left: 20px;
font-size: 20px;
opacity: 0;
transition: opacity 0.3s ease;
}
.power-up-display.active {
opacity: 1;
}
.streak-display {
font-size: 18px;
color: #d4af37;
margin-top: 10px;
text-shadow: 1px 1px 2px rgba(0,0,0,0.5);
font-family: 'Georgia', serif;
}
.power-up-display {
position: absolute;
top: 20px;
left: 20px;
font-size: 20px;
opacity: 0;
transition: opacity 0.3s ease;
background: linear-gradient(145deg, #4a3525, #2e1f15);
padding: 10px 20px;
border-radius: 12px;
border: 2px solid #1a0f08;
box-shadow:
inset 0 2px 8px rgba(255,255,255,0.1),
inset 0 -2px 8px rgba(0,0,0,0.8),
0 4px 8px rgba(0,0,0,0.6);
color: #d4af37;
text-shadow: 1px 1px 2px rgba(0,0,0,0.5);
}
.power-up-display.active {
opacity: 1;
}
.game-state-content {
text-align: center;
padding: 40px 20px;
animation: fadeIn 0.5s ease;
}
.game-state-content h2 {
font-size: 36px;
margin-bottom: 20px;
color: #5a4012;
text-shadow: 1px 1px 2px rgba(255,255,255,0.5);
font-family: 'Times New Roman', serif;
font-weight: bold;
}
.game-state-content p {
font-size: 18px;
margin-bottom: 30px;
color: #3d2a0c;
font-weight: 500;
}
.game-state-content ul {
list-style: none;
padding: 0;
}
.game-state-content li {
margin: 10px 0;
color: #4a3525;
font-size: 16px;
font-weight: 500;
}
.game-state-content li::before {
content: '✨ ';
color: #8b6914;
}
.game-state-content button {
font-size: 20px;
padding: 15px 30px;
}
.start-content {
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
max-height: 100%;
overflow: hidden;
}
.final-stats {
background: linear-gradient(145deg, #4a3525, #2e1f15);
padding: 20px;
border-radius: 10px;
margin: 20px 0;
border: 2px solid #1a0f08;
box-shadow:
inset 0 2px 8px rgba(255,255,255,0.1),
inset 0 -2px 8px rgba(0,0,0,0.8);
}
.final-stats p {
margin: 10px 0;
font-size: 20px;
color: #f5deb3;
}
.final-stats strong {
color: #ffd700;
font-size: 24px;
text-shadow: 1px 1px 2px rgba(0,0,0,0.5);
}
@keyframes fadeIn {
from {
opacity: 0;
transform: translateY(20px);
}
to {
opacity: 1;
transform: translateY(0);
}
}
@media (max-width: 600px) {
h1 { font-size: 32px; }
.scrambled-word { font-size: 32px; }
#guessInput { width: 250px; font-size: 20px; }
button { padding: 8px 16px; font-size: 14px; }
.game-container { min-height: auto; padding: 10px; }
.word-container { height: 200px; min-height: 200px; padding: 20px; }
.letter { width: 40px; height: 40px; font-size: 20px; margin: 3px; }
.game-state-content h2 { font-size: 28px; color: #5a4012; }
.game-state-content p { font-size: 14px; color: #3d2a0c; }
.game-state-content li { font-size: 13px; margin: 5px 0; color: #4a3525; }
.game-state-content button { font-size: 16px; padding: 12px 24px; }
.info-item { padding: 10px 15px; }
.score, .timer, .level { font-size: 20px; }
}
</style>
</head>
<body>
<div class="combo-display" id="comboDisplay">
COMBO x<span id="comboCount">0</span>
</div>
<div class="power-up-display" id="powerUpDisplay">
<!-- Power-up Anzeige -->
</div>
<div class="game-container">
<div class="header">
<h1>WORD SCRAMBLE</h1>
</div>
<div class="game-info">
<div class="info-item">
<div class="score">Punkte: <span id="score">0</span></div>
</div>
<div class="info-item">
<div class="level">Level: <span id="level">1</span></div>
</div>
<div class="info-item">
<div class="timer">Zeit: <span id="timer">60</span>s</div>
</div>
</div>
<div class="word-container" id="wordContainer">
<div class="category-display" id="categoryDisplay">
Kategorie: <span id="currentCategory">Tiere</span>
</div>
<div class="scrambled-word" id="scrambledWord" style="display: none;">
<!-- Durcheinandergewürfelte Buchstaben -->
</div>
<div class="hint-text" id="hintText" style="visibility: hidden;">
&nbsp;
</div>
<div class="game-state-content" id="gameStateContent">
<!-- Start und Game Over Inhalt kommt hier rein -->
</div>
</div>
<div class="input-container" id="inputContainer" style="display: none;">
<input type="text" id="guessInput" placeholder="Deine Antwort..." autocomplete="off">
</div>
<div class="buttons" id="gameButtons" style="display: none;">
<button class="submit-btn" onclick="checkAnswer()">Prüfen</button>
<button class="hint-btn" onclick="getHint()">Hinweis (-10 Punkte)</button>
<button class="skip-btn" onclick="skipWord()">Überspringen (-20 Punkte)</button>
</div>
<div class="streak-display" id="streakDisplay" style="display: none;">
Aktuelle Serie: <span id="streakCount">0</span>
</div>
</div>
<script>
// Game ID für Statistiken
const GAME_ID = 'word-scramble';
// Wortlisten nach Kategorien
const wordCategories = {
tiere: {
name: 'Tiere',
words: [
{ word: 'KATZE', hint: 'Beliebtes Haustier, miaut' },
{ word: 'HUND', hint: 'Der beste Freund des Menschen' },
{ word: 'ELEFANT', hint: 'Größtes Landtier mit Rüssel' },
{ word: 'LÖWE', hint: 'König der Tiere' },
{ word: 'TIGER', hint: 'Gestreifte Großkatze' },
{ word: 'AFFE', hint: 'Klettert auf Bäumen' },
{ word: 'PFERD', hint: 'Man kann darauf reiten' },
{ word: 'VOGEL', hint: 'Kann fliegen' },
{ word: 'FISCH', hint: 'Lebt im Wasser' },
{ word: 'KANINCHEN', hint: 'Hat lange Ohren' },
{ word: 'GIRAFFE', hint: 'Hat einen langen Hals' },
{ word: 'ZEBRA', hint: 'Schwarz-weiß gestreift' },
{ word: 'KROKODIL', hint: 'Gefährliches Reptil' },
{ word: 'PAPAGEI', hint: 'Bunter Vogel, kann sprechen' },
{ word: 'DELFIN', hint: 'Intelligentes Meerestier' }
]
},
essen: {
name: 'Essen & Trinken',
words: [
{ word: 'PIZZA', hint: 'Italienisches Gericht mit Käse' },
{ word: 'APFEL', hint: 'Runde Frucht, oft rot oder grün' },
{ word: 'BROT', hint: 'Grundnahrungsmittel aus Mehl' },
{ word: 'KÄSE', hint: 'Milchprodukt' },
{ word: 'NUDELN', hint: 'Pasta aus Italien' },
{ word: 'TOMATE', hint: 'Rotes Gemüse für Salat' },
{ word: 'BANANE', hint: 'Gelbe, gebogene Frucht' },
{ word: 'SCHOKOLADE', hint: 'Süße Leckerei aus Kakao' },
{ word: 'HAMBURGER', hint: 'Fast Food mit Fleisch' },
{ word: 'SALAT', hint: 'Gesundes, grünes Gericht' },
{ word: 'KUCHEN', hint: 'Süßes Gebäck' },
{ word: 'ORANGE', hint: 'Zitrusfrucht' },
{ word: 'KARTOFFEL', hint: 'Knolle, wächst unter der Erde' },
{ word: 'ERDBEERE', hint: 'Rote Frucht mit Punkten' },
{ word: 'MELONE', hint: 'Große, süße Frucht' }
]
},
berufe: {
name: 'Berufe',
words: [
{ word: 'ARZT', hint: 'Hilft kranken Menschen' },
{ word: 'LEHRER', hint: 'Unterrichtet in der Schule' },
{ word: 'POLIZIST', hint: 'Sorgt für Recht und Ordnung' },
{ word: 'KOCH', hint: 'Bereitet Essen zu' },
{ word: 'PILOT', hint: 'Fliegt Flugzeuge' },
{ word: 'BÄCKER', hint: 'Backt Brot und Brötchen' },
{ word: 'FEUERWEHR', hint: 'Löscht Brände' },
{ word: 'KÜNSTLER', hint: 'Malt Bilder' },
{ word: 'MUSIKER', hint: 'Macht Musik' },
{ word: 'FOTOGRAF', hint: 'Macht Fotos' },
{ word: 'GÄRTNER', hint: 'Pflegt Pflanzen' },
{ word: 'MECHANIKER', hint: 'Repariert Autos' },
{ word: 'VERKÄUFER', hint: 'Arbeitet im Geschäft' },
{ word: 'JOURNALIST', hint: 'Schreibt Artikel' },
{ word: 'ARCHITEKT', hint: 'Entwirft Gebäude' }
]
},
länder: {
name: 'Länder',
words: [
{ word: 'DEUTSCHLAND', hint: 'Land in Mitteleuropa' },
{ word: 'FRANKREICH', hint: 'Land mit Eiffelturm' },
{ word: 'ITALIEN', hint: 'Stiefelförmiges Land' },
{ word: 'SPANIEN', hint: 'Land mit Flamenco' },
{ word: 'ENGLAND', hint: 'Land mit Queen' },
{ word: 'AMERIKA', hint: 'Land der unbegrenzten Möglichkeiten' },
{ word: 'CHINA', hint: 'Bevölkerungsreichstes Land' },
{ word: 'JAPAN', hint: 'Land der aufgehenden Sonne' },
{ word: 'AUSTRALIEN', hint: 'Land der Kängurus' },
{ word: 'BRASILIEN', hint: 'Größtes Land Südamerikas' },
{ word: 'KANADA', hint: 'Nördlicher Nachbar der USA' },
{ word: 'MEXIKO', hint: 'Land der Azteken' },
{ word: 'INDIEN', hint: 'Land mit Taj Mahal' },
{ word: 'RUSSLAND', hint: 'Größtes Land der Welt' },
{ word: 'ÄGYPTEN', hint: 'Land der Pyramiden' }
]
},
sport: {
name: 'Sport',
words: [
{ word: 'FUSSBALL', hint: 'Beliebtester Sport der Welt' },
{ word: 'TENNIS', hint: 'Sport mit Schläger und Ball' },
{ word: 'BASKETBALL', hint: 'Sport mit Korb' },
{ word: 'SCHWIMMEN', hint: 'Sport im Wasser' },
{ word: 'LAUFEN', hint: 'Einfachste Sportart' },
{ word: 'RADFAHREN', hint: 'Sport auf zwei Rädern' },
{ word: 'BOXEN', hint: 'Kampfsport mit Handschuhen' },
{ word: 'GOLF', hint: 'Sport mit kleinem Ball und Löchern' },
{ word: 'SKIFAHREN', hint: 'Wintersport auf Brettern' },
{ word: 'VOLLEYBALL', hint: 'Sport mit Netz' },
{ word: 'HANDBALL', hint: 'Sport mit Tor und Ball' },
{ word: 'EISHOCKEY', hint: 'Sport auf Eis' },
{ word: 'TURNEN', hint: 'Sport mit Geräten' },
{ word: 'REITEN', hint: 'Sport mit Pferden' },
{ word: 'SURFEN', hint: 'Sport auf Wellen' }
]
}
};
// Spielvariablen
let currentCategory = 'tiere';
let currentWord = null;
let scrambledWord = '';
let score = 0;
let level = 1;
let timeLeft = 60;
let gameRunning = false;
let combo = 0;
let streak = 0;
let hintsUsed = 0;
let wordsCompleted = 0;
let timerInterval = null;
let wordStartTime = 0;
// DOM Elemente
const scrambledWordElement = document.getElementById('scrambledWord');
const guessInput = document.getElementById('guessInput');
const scoreElement = document.getElementById('score');
const levelElement = document.getElementById('level');
const timerElement = document.getElementById('timer');
const hintTextElement = document.getElementById('hintText');
const categoryElement = document.getElementById('currentCategory');
const comboDisplay = document.getElementById('comboDisplay');
const comboCount = document.getElementById('comboCount');
const streakCount = document.getElementById('streakCount');
const gameStateContent = document.getElementById('gameStateContent');
// Wort scramble Funktion
function scrambleWord(word) {
const letters = word.split('');
let scrambled;
// Stelle sicher, dass das Wort wirklich durcheinander ist
do {
scrambled = letters.sort(() => Math.random() - 0.5).join('');
} while (scrambled === word && word.length > 2);
return scrambled;
}
// Neues Wort wählen
function selectNewWord() {
const categories = Object.keys(wordCategories);
// Wechsle Kategorie alle 5 Wörter
if (wordsCompleted > 0 && wordsCompleted % 5 === 0) {
const currentIndex = categories.indexOf(currentCategory);
currentCategory = categories[(currentIndex + 1) % categories.length];
categoryElement.textContent = wordCategories[currentCategory].name;
// Zeige Kategorie-Wechsel Animation
createNotification(`Neue Kategorie: ${wordCategories[currentCategory].name}`, '#4ecdc4');
}
const categoryWords = wordCategories[currentCategory].words;
currentWord = categoryWords[Math.floor(Math.random() * categoryWords.length)];
scrambledWord = scrambleWord(currentWord.word);
wordStartTime = Date.now();
displayScrambledWord();
guessInput.value = '';
hintTextElement.textContent = '';
hintsUsed = 0;
}
// Zeige durcheinandergewürfelte Buchstaben
function displayScrambledWord() {
scrambledWordElement.innerHTML = '';
scrambledWord.split('').forEach((letter, index) => {
const span = document.createElement('span');
span.className = 'letter';
span.textContent = letter;
span.style.animationDelay = `${index * 0.1}s`;
// Klick auf Buchstabe fügt ihn zum Input hinzu
span.onclick = () => {
guessInput.value += letter;
guessInput.focus();
};
scrambledWordElement.appendChild(span);
});
}
// Antwort prüfen
function checkAnswer() {
const guess = guessInput.value.toUpperCase().trim();
if (!gameRunning || !guess) return;
if (guess === currentWord.word) {
// Richtige Antwort
const timeBonus = Math.max(0, 30 - Math.floor((Date.now() - wordStartTime) / 1000));
const baseScore = currentWord.word.length * 10;
const comboBonus = combo * 5;
const totalScore = baseScore + timeBonus + comboBonus - (hintsUsed * 10);
score += totalScore;
combo++;
streak++;
wordsCompleted++;
updateUI();
showSuccess(totalScore);
// Level erhöhen
if (wordsCompleted % 10 === 0) {
level++;
timeLeft += 30; // Bonus Zeit für neues Level
createNotification(`Level ${level} erreicht! +30 Sekunden`, '#ffd700');
}
selectNewWord();
} else {
// Falsche Antwort
combo = 0;
shakeInput();
createNotification('Falsch! Versuche es nochmal', '#ff6b6b');
}
}
// Hinweis geben
function getHint() {
if (!gameRunning || hintsUsed >= 2) return;
hintsUsed++;
score = Math.max(0, score - 10);
if (hintsUsed === 1) {
// Erster Hinweis: Beschreibung
hintTextElement.textContent = `Hinweis: ${currentWord.hint}`;
} else if (hintsUsed === 2) {
// Zweiter Hinweis: Erster und letzter Buchstabe
const word = currentWord.word;
const hint = word[0] + ' _ '.repeat(word.length - 2) + word[word.length - 1];
hintTextElement.textContent = `Wort: ${hint}`;
}
updateUI();
}
// Wort überspringen
function skipWord() {
if (!gameRunning) return;
score = Math.max(0, score - 20);
combo = 0;
streak = 0;
createNotification(`Übersprungen! Das Wort war: ${currentWord.word}`, '#ff6b6b');
selectNewWord();
updateUI();
}
// UI aktualisieren
function updateUI() {
scoreElement.textContent = score;
levelElement.textContent = level;
streakCount.textContent = streak;
// Streak-Anzeige nur bei laufendem Spiel
const streakDisplay = document.getElementById('streakDisplay');
if (gameRunning && streak > 0) {
streakDisplay.classList.add('visible');
} else {
streakDisplay.classList.remove('visible');
}
if (combo > 1) {
comboDisplay.classList.add('active');
comboCount.textContent = combo;
} else {
comboDisplay.classList.remove('active');
}
}
// Erfolgs-Animation
function showSuccess(points) {
createParticles(guessInput.getBoundingClientRect());
createNotification(`+${points} Punkte!`, '#4ecdc4');
// Sende Score Update
window.parent.postMessage({
type: 'GAME_EVENT',
gameId: GAME_ID,
event: 'SCORE_UPDATE',
data: { score: score }
}, '*');
}
// Input schütteln bei falscher Antwort
function shakeInput() {
guessInput.style.animation = 'shake 0.5s';
setTimeout(() => {
guessInput.style.animation = '';
}, 500);
}
// Partikel-Effekt erstellen
function createParticles(rect) {
for (let i = 0; i < 10; i++) {
const particle = document.createElement('div');
particle.className = 'particle';
particle.textContent = '✨';
particle.style.left = rect.left + rect.width / 2 + 'px';
particle.style.top = rect.top + 'px';
particle.style.fontSize = Math.random() * 20 + 10 + 'px';
document.body.appendChild(particle);
setTimeout(() => particle.remove(), 1000);
}
}
// Benachrichtigung erstellen
function createNotification(text, color) {
const notification = document.createElement('div');
notification.style.cssText = `
position: fixed;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
background: ${color};
color: white;
padding: 20px 40px;
border-radius: 50px;
font-size: 24px;
font-weight: bold;
z-index: 1000;
animation: fadeInOut 2s ease;
`;
notification.textContent = text;
document.body.appendChild(notification);
setTimeout(() => notification.remove(), 2000);
}
// Timer
function startTimer() {
timerInterval = setInterval(() => {
if (timeLeft > 0 && gameRunning) {
timeLeft--;
timerElement.textContent = timeLeft;
if (timeLeft <= 10) {
timerElement.style.color = '#ff0000';
}
} else if (timeLeft === 0) {
gameOver();
}
}, 1000);
}
// Spiel starten
function startGame() {
// Verstecke den Start-Inhalt
document.getElementById('gameStateContent').style.display = 'none';
// Zeige die Spiel-Elemente
document.getElementById('categoryDisplay').style.display = 'block';
document.getElementById('scrambledWord').style.display = 'flex';
document.getElementById('hintText').style.display = 'flex';
document.getElementById('hintText').style.visibility = 'visible';
document.querySelector('.input-container').style.display = 'flex';
document.querySelector('.buttons').style.display = 'flex';
gameRunning = true;
score = 0;
level = 1;
timeLeft = 60;
combo = 0;
streak = 0;
wordsCompleted = 0;
updateUI();
selectNewWord();
startTimer();
guessInput.focus();
// Sende Game Loaded Event
window.parent.postMessage({
type: 'GAME_LOADED',
gameId: GAME_ID
}, '*');
}
// Game Over
function gameOver() {
gameRunning = false;
clearInterval(timerInterval);
// Verstecke die Spiel-Elemente
document.getElementById('scrambledWord').style.display = 'none';
document.getElementById('hintText').style.display = 'none';
document.querySelector('.input-container').style.display = 'none';
document.querySelector('.buttons').style.display = 'none';
// Zeige Game Over Inhalt
const gameStateContent = document.getElementById('gameStateContent');
gameStateContent.innerHTML = `
<h2>Spiel beendet!</h2>
<div class="final-stats">
<p>Endpunktzahl: <strong>${score}</strong></p>
<p>Level erreicht: <strong>${level}</strong></p>
<p>Wörter gelöst: <strong>${wordsCompleted}</strong></p>
</div>
<button class="btn btn-primary" onclick="location.reload()">Nochmal spielen</button>
`;
gameStateContent.style.display = 'block';
// Sende Game Over Event
window.parent.postMessage({
type: 'GAME_EVENT',
gameId: GAME_ID,
event: 'GAME_OVER',
data: { score: score }
}, '*');
// Achievement prüfen
if (score >= 1000) {
window.parent.postMessage({
type: 'GAME_EVENT',
gameId: GAME_ID,
event: 'ACHIEVEMENT_UNLOCKED',
data: {
achievementId: 'word_master',
name: 'Wortmeister',
description: '1000 Punkte in Word Scramble erreicht',
icon: '🏆'
}
}, '*');
}
if (combo >= 10) {
window.parent.postMessage({
type: 'GAME_EVENT',
gameId: GAME_ID,
event: 'ACHIEVEMENT_UNLOCKED',
data: {
achievementId: 'combo_genius',
name: 'Combo Genie',
description: '10er Combo in Word Scramble',
icon: '🔥'
}
}, '*');
}
if (wordsCompleted >= 30) {
window.parent.postMessage({
type: 'GAME_EVENT',
gameId: GAME_ID,
event: 'ACHIEVEMENT_UNLOCKED',
data: {
achievementId: 'vocabulary_king',
name: 'Vokabel König',
description: '30 Wörter in einem Spiel gelöst',
icon: '👑'
}
}, '*');
}
}
// Initialisierung beim Laden der Seite
window.addEventListener('load', () => {
// Zeige Start-Inhalt
gameStateContent.innerHTML = `
<h2>Word Scramble</h2>
<p>Entschlüssele durcheinandergewürfelte Wörter!</p>
<ul style="text-align: left; max-width: 300px; margin: 20px auto;">
<li>5 verschiedene Kategorien</li>
<li>Combo-System für schnelle Antworten</li>
<li>Hinweise verfügbar</li>
<li>Zeit-Bonus für schnelle Lösungen</li>
</ul>
<button class="btn btn-primary" onclick="startGame()">Spiel starten</button>
`;
// Verstecke Spiel-Elemente initial
document.getElementById('scrambledWord').style.display = 'none';
document.getElementById('hintText').style.display = 'none';
document.getElementById('categoryDisplay').style.display = 'none';
document.querySelector('.input-container').style.display = 'none';
document.querySelector('.buttons').style.display = 'none';
});
// Event Listener
guessInput.addEventListener('keypress', (e) => {
if (e.key === 'Enter') {
checkAnswer();
}
});
// CSS für Shake Animation hinzufügen
const style = document.createElement('style');
style.textContent = `
@keyframes shake {
0%, 100% { transform: translateX(0); }
25% { transform: translateX(-10px); }
75% { transform: translateX(10px); }
}
@keyframes fadeInOut {
0% { opacity: 0; transform: translate(-50%, -50%) scale(0.8); }
20% { opacity: 1; transform: translate(-50%, -50%) scale(1); }
80% { opacity: 1; transform: translate(-50%, -50%) scale(1); }
100% { opacity: 0; transform: translate(-50%, -50%) scale(0.8); }
}
`;
document.head.appendChild(style);
</script>
</body>
</html>