Start
JavaScript
Memory Spiel programmieren
🧠 Memory – JavaScript Spiel programmieren
In dieser Anleitung lernst du Schritt für Schritt, wie du das klassische Memory (Paare finden) Spiel in JavaScript programmierst.
Du baust ein Spiel mit 20 Karten (10 Paaren) und schönen Symbolen.
📝 Was du brauchst:
✅ Einen Texteditor (z.B. Notepad, VS Code)
✅ Einen Webbrowser (Chrome, Firefox, Safari)
✅ Lust auf ein kniffliges Gedächtnisspiel!
🎯 Das fertige Memory-Spiel – zum Ausprobieren!
Klicke auf Karten und finde die passenden Paare!
🧠 MEMORY
20 Karten
🎯 Finde die Paare!
🔄 Neues Spiel
💡 Klicke auf zwei Karten – finde das passende Paar!
📚 Schritt-für-Schritt Anleitung
Kopiere den Code aus jedem Schritt in deine Datei und teste ihn!
1
HTML-Grundgerüst erstellen
Erstelle eine neue Datei mit dem Namen memory.html. Füge dieses Grundgerüst ein:
<!DOCTYPE html>
<html>
<head>
<title>Memory</title>
<style>
body {
display: flex;
justify-content: center;
align-items: center;
min-height: 100vh;
background: #1a1a2e;
font-family: Arial, sans-serif;
margin: 0;
padding: 20px;
}
.container {
background: #2d2d44;
padding: 30px;
border-radius: 20px;
box-shadow: 0 10px 30px rgba(0,0,0,0.5);
text-align: center;
}
.grid {
display: grid;
grid-template-columns: repeat(5, 80px);
gap: 10px;
margin: 20px 0;
}
.card {
width: 80px;
height: 80px;
background: #4a6fa5;
border-radius: 12px;
display: flex;
align-items: center;
justify-content: center;
font-size: 36px;
cursor: pointer;
transition: all 0.3s;
color: white;
border: 2px solid #6a8fc5;
user-select: none;
}
.card.flipped {
background: #2d2d44;
border-color: #89b4fa;
}
.card.matched {
background: #2d5a2d;
border-color: #6bcb77;
cursor: default;
opacity: 0.7;
}
.card:hover:not(.flipped):not(.matched) {
transform: scale(1.05);
}
.status {
color: white;
font-size: 22px;
margin: 15px 0;
}
.reset {
background: #ff6b6b;
border: none;
color: white;
padding: 10px 30px;
border-radius: 10px;
font-size: 18px;
cursor: pointer;
}
</style>
</head>
<body>
<div class="container">
<h1 style="color: white;">🧠 Memory</h1>
<div class="grid" id="grid"></div>
<div class="status" id="status">Finde die Paare!</div>
<button class="reset" id="reset">🔄 Neues Spiel</button>
</div>
<script>
// Hier kommt später der JavaScript-Code rein
console.log("Memory geladen!");
</script>
</body>
</html>
✅ Teste es! Öffne die Datei im Browser. Du siehst einen leeren Bereich mit Überschrift und Button.
2
Symbole und Spielvariablen definieren
Ersetze den Inhalt von <script> mit diesem Code:
const SYMBOLS = ['🐶', '🐱', '🐭', '🐹', '🐰', '🦊', '🐻', '🐼', '🐨', '🐯'];
const grid = document.getElementById('grid');
const statusDisplay = document.getElementById('status');
const resetButton = document.getElementById('reset');
let cards = [];
let flippedCards = [];
let matchedPairs = 0;
let isLocked = false;
let moves = 0;
let timer = null;
let seconds = 0;
console.log('✅ Memory geladen! Symbole:', SYMBOLS);
✅ Teste es! In der Konsole siehst du die Symbole und die Meldung.
3
Karten mischen und anzeigen
Füge diese Funktionen hinzu:
function shuffle(array) {
for (let i = array.length - 1; i > 0; i--) {
const j = Math.floor(Math.random() * (i + 1));
[array[i], array[j]] = [array[j], array[i]];
}
return array;
}
function initGame() {
let deck = [...SYMBOLS, ...SYMBOLS];
deck = shuffle(deck);
cards = deck.map((symbol, index) => ({
id: index,
symbol: symbol,
flipped: false,
matched: false
}));
flippedCards = [];
matchedPairs = 0;
isLocked = false;
moves = 0;
seconds = 0;
clearInterval(timer);
timer = null;
renderCards();
updateStatus();
}
function renderCards() {
grid.innerHTML = '';
cards.forEach((card, index) => {
const cardElement = document.createElement('div');
cardElement.className = 'card';
cardElement.dataset.index = index;
if (card.flipped) {
cardElement.classList.add('flipped');
cardElement.textContent = card.symbol;
} else {
cardElement.textContent = '?';
}
if (card.matched) {
cardElement.classList.add('matched');
cardElement.textContent = card.symbol;
}
cardElement.addEventListener('click', () => handleCardClick(index));
grid.appendChild(cardElement);
});
}
function updateStatus() {
const totalPairs = SYMBOLS.length;
if (matchedPairs === totalPairs) {
statusDisplay.textContent = `🎉 Gewonnen! ${moves} Züge, ${seconds}s`;
} else {
statusDisplay.textContent = `🧠 ${matchedPairs}/${totalPairs} Paare gefunden • ${moves} Züge`;
}
}
initGame();
✅ Teste es! Du siehst 20 Karten mit "?" – das sind deine verdeckten Memory-Karten!
4
Klick-Logik: Karten umdrehen und Paare prüfen
Füge diese Funktionen hinzu:
function flipCard(index) {
const card = cards[index];
if (card.flipped || card.matched || isLocked) return false;
card.flipped = true;
flippedCards.push(index);
renderCards();
return true;
}
function checkMatch() {
const [idx1, idx2] = flippedCards;
const card1 = cards[idx1];
const card2 = cards[idx2];
if (card1.symbol === card2.symbol) {
card1.matched = true;
card2.matched = true;
matchedPairs++;
flippedCards = [];
updateStatus();
renderCards();
if (matchedPairs === SYMBOLS.length) {
clearInterval(timer);
statusDisplay.textContent = `🎉 Gewonnen! ${moves} Züge, ${seconds}s`;
}
return true;
}
return false;
}
function resetFlipped() {
isLocked = true;
setTimeout(() => {
cards.forEach((card) => {
if (card.flipped && !card.matched) {
card.flipped = false;
}
});
flippedCards = [];
isLocked = false;
renderCards();
}, 600);
}
function handleCardClick(index) {
if (isLocked) return;
if (flippedCards.length >= 2) return;
if (cards[index].flipped || cards[index].matched) return;
if (moves === 0 && matchedPairs === 0) {
timer = setInterval(() => {
seconds++;
if (matchedPairs < SYMBOLS.length) {
updateStatus();
}
}, 1000);
}
flipCard(index);
moves++;
if (flippedCards.length === 2) {
const match = checkMatch();
if (!match) {
resetFlipped();
}
updateStatus();
} else {
updateStatus();
}
}
✅ Teste es! Klicke auf Karten – sie drehen sich um und zeigen Symbole!
Finde zwei gleiche – sie bleiben offen!
5
Reset-Button und Timer
Füge den Reset-Button und den Timer-Code hinzu:
function resetGame() {
clearInterval(timer);
timer = null;
seconds = 0;
initGame();
}
resetButton.addEventListener('click', resetGame);
initGame();
✅ Teste es! Klicke auf "Neues Spiel" – das Spiel wird zurückgesetzt!
Der Timer startet beim ersten Klick und stoppt, wenn alle Paare gefunden sind.
📋 Kompletter Code – perfekt zum Reinkopieren!
Hier ist der ganze Memory-Code mit allen Funktionen.
<!DOCTYPE html>
<html>
<head>
<title>Memory</title>
<style>
body {
display: flex;
justify-content: center;
align-items: center;
min-height: 100vh;
background: #1a1a2e;
font-family: Arial, sans-serif;
margin: 0;
padding: 20px;
}
.container {
background: #2d2d44;
padding: 30px;
border-radius: 20px;
box-shadow: 0 10px 30px rgba(0,0,0,0.5);
text-align: center;
max-width: 700px;
width: 100%;
}
.grid {
display: grid;
grid-template-columns: repeat(5, 1fr);
gap: 10px;
margin: 20px 0;
}
.card {
aspect-ratio: 1 / 1;
background: #4a6fa5;
border-radius: 12px;
display: flex;
align-items: center;
justify-content: center;
font-size: 36px;
cursor: pointer;
transition: all 0.3s;
color: white;
border: 2px solid #6a8fc5;
user-select: none;
font-weight: bold;
}
.card.flipped {
background: #2d2d44;
border-color: #89b4fa;
}
.card.matched {
background: #2d5a2d;
border-color: #6bcb77;
cursor: default;
opacity: 0.8;
}
.card:hover:not(.flipped):not(.matched) {
transform: scale(1.05);
border-color: #89b4fa;
}
.status {
color: white;
font-size: 22px;
margin: 15px 0;
padding: 10px;
background: #1a1a2e;
border-radius: 10px;
}
.reset {
background: #ff6b6b;
border: none;
color: white;
padding: 10px 30px;
border-radius: 10px;
font-size: 18px;
cursor: pointer;
transition: all 0.2s;
}
.reset:hover {
transform: scale(1.05);
}
@media (max-width: 500px) {
.card { font-size: 24px; }
.grid { gap: 6px; }
}
@media (max-width: 380px) {
.card { font-size: 18px; }
}
</style>
</head>
<body>
<div class="container">
<h1 style="color: white;">🧠 Memory</h1>
<div class="grid" id="grid"></div>
<div class="status" id="status">Finde die Paare!</div>
<button class="reset" id="reset">🔄 Neues Spiel</button>
</div>
<script>
const SYMBOLS = ['🐶', '🐱', '🐭', '🐹', '🐰', '🦊', '🐻', '🐼', '🐨', '🐯'];
const grid = document.getElementById('grid');
const statusDisplay = document.getElementById('status');
const resetButton = document.getElementById('reset');
let cards = [];
let flippedCards = [];
let matchedPairs = 0;
let isLocked = false;
let moves = 0;
let timer = null;
let seconds = 0;
function shuffle(array) {
for (let i = array.length - 1; i > 0; i--) {
const j = Math.floor(Math.random() * (i + 1));
[array[i], array[j]] = [array[j], array[i]];
}
return array;
}
function initGame() {
let deck = [...SYMBOLS, ...SYMBOLS];
deck = shuffle(deck);
cards = deck.map((symbol, index) => ({
id: index,
symbol: symbol,
flipped: false,
matched: false
}));
flippedCards = [];
matchedPairs = 0;
isLocked = false;
moves = 0;
seconds = 0;
clearInterval(timer);
timer = null;
renderCards();
updateStatus();
}
function renderCards() {
grid.innerHTML = '';
cards.forEach((card, index) => {
const cardElement = document.createElement('div');
cardElement.className = 'card';
cardElement.dataset.index = index;
if (card.flipped || card.matched) {
cardElement.classList.add('flipped');
cardElement.textContent = card.symbol;
} else {
cardElement.textContent = '?';
}
if (card.matched) {
cardElement.classList.add('matched');
}
cardElement.addEventListener('click', () => handleCardClick(index));
grid.appendChild(cardElement);
});
}
function updateStatus() {
const totalPairs = SYMBOLS.length;
if (matchedPairs === totalPairs) {
statusDisplay.textContent = `🎉 Gewonnen! ${moves} Züge, ${seconds}s`;
} else {
statusDisplay.textContent = `🧠 ${matchedPairs}/${totalPairs} Paare • ${moves} Züge`;
}
}
function flipCard(index) {
const card = cards[index];
if (card.flipped || card.matched || isLocked) return false;
card.flipped = true;
flippedCards.push(index);
renderCards();
return true;
}
function checkMatch() {
const [idx1, idx2] = flippedCards;
const card1 = cards[idx1];
const card2 = cards[idx2];
if (card1.symbol === card2.symbol) {
card1.matched = true;
card2.matched = true;
matchedPairs++;
flippedCards = [];
updateStatus();
renderCards();
if (matchedPairs === SYMBOLS.length) {
clearInterval(timer);
statusDisplay.textContent = `🎉 Gewonnen! ${moves} Züge, ${seconds}s`;
}
return true;
}
return false;
}
function resetFlipped() {
isLocked = true;
setTimeout(() => {
cards.forEach((card) => {
if (card.flipped && !card.matched) {
card.flipped = false;
}
});
flippedCards = [];
isLocked = false;
renderCards();
}, 600);
}
function handleCardClick(index) {
if (isLocked) return;
if (flippedCards.length >= 2) return;
if (cards[index].flipped || cards[index].matched) return;
if (moves === 0 && matchedPairs === 0) {
timer = setInterval(() => {
seconds++;
if (matchedPairs < SYMBOLS.length) {
updateStatus();
}
}, 1000);
}
flipCard(index);
moves++;
if (flippedCards.length === 2) {
const match = checkMatch();
if (!match) {
resetFlipped();
}
updateStatus();
} else {
updateStatus();
}
}
function resetGame() {
clearInterval(timer);
timer = null;
seconds = 0;
initGame();
}
resetButton.addEventListener('click', resetGame);
initGame();
</script>
</body>
</html>
🎯 JETZT BIST DU DRAN!
1. Kopiere den kompletten Code in eine neue Datei.
2. Speichere sie als memory.html.
3. Öffne die Datei im Browser.
4. Finde alle Paare – viel Spaß!
💡 Erweiterungsideen:
- Füge mehr Symbole hinzu (z.B. 🦄, 🐉, 🐧)
- Ändere die Anzahl der Karten (z.B. 4x4 = 16 Karten)
- Füge einen Highscore (bestes Ergebnis) hinzu
🎉 GLÜCKWUNSCH!
Du hast dein eigenes Memory-Spiel programmiert!
Du hast gelernt, wie man Karten mischt, umdreht und Paare findet –
und sogar einen Timer eingebaut!