🎮 Membuat Game Memory Card Interaktif dengan HTML, CSS, dan JavaScript
🎮 Apa Itu Game Memory Card?
Memory Card adalah game mencocokkan pasangan kartu yang mengasah ingatan. Dalam game ini, pemain akan:
- Membalik dua kartu
- Jika cocok, kartu akan tetap terbuka
- Jika tidak cocok, kartu akan tertutup kembali
Kita akan buat game ini responsif, penuh warna, dan dilengkapi suara interaktif!
🔧 Fitur-Fitur Game
| Fitur | Penjelasan |
| Mode Gelap | Tampilan modern dan nyaman di mata |
| Skor | Bertambah jika menemukan pasangan yang cocok |
| Timer | Menghitung waktu dari awal game |
| Efek Suara | Flip, match, dan wrong – membuat game lebih hidup |
| Restart Game | Tombol untuk memulai ulang kapan saja |
🧩 Struktur Proyek
/memory-card-game
│
├── index.html
├── style.css
├── script.js
└── sounds/
├── flip.mp3
├── match.mp3
└── wrong.mp3
🔗 Link Download Efek Suara Gratis
Letakkan file di dalam folder sounds/:
Klik kanan → “Save link as...” untuk menyimpannya.
💻 Kode Lengkap
✅ index.html
<!DOCTYPE html>
<html lang="id">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0"/>
<title>Memory Card Game</title>
<link rel="stylesheet" href="style.css" />
</head>
<body>
<div class="game-container">
<h1>🎴 Memory Card Game</h1>
<div class="info-bar">
<span id="score">Skor: 0</span>
<span id="timer">Waktu: 0 detik</span>
</div>
<div class="board" id="game-board"></div>
<button id="reset">🔄 Reset Game</button>
</div>
<!-- Suara -->
<audio id="sound-flip" src="sounds/flip.mp3"></audio>
<audio id="sound-match" src="sounds/match.mp3"></audio>
<audio id="sound-wrong" src="sounds/wrong.mp3"></audio>
<script src="script.js"></script>
</body>
</html>
🎨 style.css
body {
margin: 0;
font-family: 'Segoe UI', sans-serif;
background-color: #121212;
color: #ffffff;
display: flex;
justify-content: center;
align-items: center;
min-height: 100vh;
}
.game-container {
text-align: center;
max-width: 600px;
}
h1 {
margin-bottom: 20px;
font-size: 2rem;
color: #00e5ff;
}
.board {
display: grid;
grid-template-columns: repeat(4, 100px);
gap: 15px;
justify-content: center;
}
.card {
width: 100px;
height: 100px;
background-color: #1e1e1e;
border-radius: 12px;
cursor: pointer;
perspective: 1000px;
position: relative;
transition: transform 0.3s;
}
.card.flip .card-inner {
transform: rotateY(180deg);
}
.card-inner {
width: 100%;
height: 100%;
transform-style: preserve-3d;
transition: transform 0.6s;
position: relative;
}
.card-front, .card-back {
width: 100%;
height: 100%;
position: absolute;
border-radius: 12px;
backface-visibility: hidden;
display: flex;
justify-content: center;
align-items: center;
font-size: 2rem;
}
.card-front {
background-color: #333;
color: #fff;
}
.card-back {
transform: rotateY(180deg);
color: #fff;
font-weight: bold;
}
button#reset {
margin-top: 20px;
padding: 10px 20px;
background: #00e5ff;
color: #121212;
border: none;
border-radius: 8px;
font-size: 1rem;
cursor: pointer;
transition: background 0.3s;
}
button#reset:hover {
background: #00bcd4;
}
.info-bar {
display: flex;
justify-content: space-between;
margin-bottom: 15px;
font-size: 1.1rem;
color: #ffeb3b;
padding: 0 10px;
}
⚙️ script.js
const colors = [
'#f44336', '#e91e63', '#9c27b0', '#3f51b5',
'#03a9f4', '#009688', '#4caf50', '#ff9800'
];
const colorPairs = [...colors, ...colors];
const totalPairs = colors.length;
let firstCard = null;
let secondCard = null;
let lockBoard = false;
let score = 0;
let matchedPairs = 0;
let timer = 0;
let timerInterval;
const board = document.getElementById('game-board');
const scoreDisplay = document.getElementById('score');
const timerDisplay = document.getElementById('timer');
const soundFlip = document.getElementById('sound-flip');
const soundMatch = document.getElementById('sound-match');
const soundWrong = document.getElementById('sound-wrong');
function shuffle(array) {
return array.sort(() => Math.random() - 0.5);
}
function createCard(color) {
const card = document.createElement('div');
card.classList.add('card');
const inner = document.createElement('div');
inner.classList.add('card-inner');
const front = document.createElement('div');
front.classList.add('card-front');
front.textContent = '?';
const back = document.createElement('div');
back.classList.add('card-back');
back.style.backgroundColor = color;
back.textContent = '✔';
inner.appendChild(front);
inner.appendChild(back);
card.appendChild(inner);
card.dataset.color = color;
card.addEventListener('click', handleFlip);
return card;
}
function handleFlip() {
if (lockBoard || this === firstCard || this.classList.contains('flip')) return;
this.classList.add('flip');
soundFlip.play();
if (!firstCard) {
firstCard = this;
return;
}
secondCard = this;
lockBoard = true;
checkForMatch();
}
function checkForMatch() {
const isMatch = firstCard.dataset.color === secondCard.dataset.color;
if (isMatch) {
handleMatch();
} else {
handleMismatch();
}
}
function handleMatch() {
soundMatch.play();
score += 10;
matchedPairs++;
updateScore();
firstCard.removeEventListener('click', handleFlip);
secondCard.removeEventListener('click', handleFlip);
resetTurn();
if (matchedPairs === totalPairs) {
clearInterval(timerInterval);
setTimeout(() => {
alert(`🎉 Kamu menang!\nSkor: ${score}\nWaktu: ${timer} detik`);
}, 500);
}
}
function handleMismatch() {
soundWrong.play();
setTimeout(() => {
firstCard.classList.remove('flip');
secondCard.classList.remove('flip');
resetTurn();
}, 800);
}
function resetTurn() {
[firstCard, secondCard] = [null, null];
lockBoard = false;
}
function updateScore() {
scoreDisplay.textContent = `Skor: ${score}`;
}
function updateTimer() {
timer++;
timerDisplay.textContent = `Waktu: ${timer} detik`;
}
function startTimer() {
clearInterval(timerInterval);
timer = 0;
timerDisplay.textContent = `Waktu: 0 detik`;
timerInterval = setInterval(updateTimer, 1000);
}
function setupGame() {
board.innerHTML = '';
shuffle(colorPairs).forEach(color => {
board.appendChild(createCard(color));
});
score = 0;
matchedPairs = 0;
updateScore();
resetTurn();
startTimer();
}
document.getElementById('reset').addEventListener('click', setupGame);
// Inisialisasi saat halaman dimuat
setupGame();
🎴 Efek Suara Membalik Kartu (Flip)
- Pixabay – Card Flipping Sound
- Suara realistis membalik kartu.
- Unduh di siniPixabay
- Orange Free Sounds – Card Flip
- Suara kartu dibalik di atas meja.
- Audio.com – Card Flip by echopulsemystic
- Suara efek membalik kartu yang halus.
✅ Efek Suara Pasangan Cocok (Match)
- Mixkit – Game Bonus
- Suara bonus kemenangan yang menyenangkan.
- Pixabay – Game Bonus
- Suara bonus kemenangan yang menyenangkan.
- Unduh di siniAudio
❌ Efek Suara Salah (Wrong)
- Pixabay – Wrong Answer
- Suara buzzer jawaban salah.
- Orange Free Sounds – Incorrect Sound
- Suara peringatan kesalahan.
🚀 Penutup
Dengan kode ini, kamu sudah bisa membuat game Memory Card interaktif yang seru dan bisa dimainkan siapa saja. Tambahkan ide-ide baru seperti level, soundtrack latar, atau leaderboard jika ingin mengembangkan lebih jauh.
Jika kamu ingin saya buatkan versi offline ZIP, GitHub deploy, atau export ke Android (WebView), tinggal bilang ya!

Komentar
Posting Komentar