Game Matematika
<!DOCTYPE html>
<html lang="id">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Permainan Perkalian</title>
<!-- Memuat Tailwind CSS -->
<script src="https://cdn.tailwindcss.com"></script>
<style>
/* Mengatur font Inter */
:root {
font-family: 'Inter', sans-serif;
}
/* Custom CSS untuk Animasi */
@keyframes correct-pop {
0% { transform: scale(0.5); opacity: 0; }
50% { transform: scale(1.5); opacity: 1; }
100% { transform: scale(1); opacity: 0; }
}
.correct-animation {
animation: correct-pop 1s ease-out forwards;
}
/* Style untuk Tombol */
.btn-primary {
transition: all 0.2s;
box-shadow: 0 4px #1c4532; /* Shadow hijau tua */
}
.btn-primary:hover {
box-shadow: 0 2px #1c4532;
transform: translateY(2px);
}
.btn-primary:active {
box-shadow: 0 0 #1c4532;
transform: translateY(4px);
}
</style>
</head>
<body class="bg-gradient-to-br from-green-100 to-blue-100 min-h-screen flex items-center justify-center p-4">
<!-- Container Utama Permainan -->
<div id="game-container" class="w-full max-w-md bg-white p-6 md:p-8 rounded-2xl shadow-2xl border-4 border-blue-500/50">
<!-- Header Informasi -->
<header class="text-center mb-6">
<h1 class="text-3xl font-extrabold text-blue-700">Latihan Perkalian (1-10)</h1>
<p class="text-gray-600 mt-1" id="user-info"></p>
</header>
<!-- Tampilan 1: Input Nama dan Sekolah -->
<div id="input-screen" class="space-y-4">
<h2 class="text-xl font-semibold text-gray-800 mb-4">Masukkan Data Diri</h2>
<div>
<label for="name-input" class="block text-sm font-medium text-gray-700 mb-1">Nama Siswa:</label>
<input type="text" id="name-input" placeholder="Contoh: Budi Santoso" class="w-full p-3 border border-gray-300 rounded-lg focus:ring-green-500 focus:border-green-500 transition duration-150 shadow-sm">
</div>
<div>
<label for="school-input" class="block text-sm font-medium text-gray-700 mb-1">Asal Sekolah:</label>
<input type="text" id="school-input" placeholder="Contoh: SD Negeri 1 Jakarta" class="w-full p-3 border border-gray-300 rounded-lg focus:ring-green-500 focus:border-green-500 transition duration-150 shadow-sm">
</div>
<button id="start-button" class="btn-primary w-full py-3 bg-green-500 text-white font-bold rounded-lg mt-4 text-lg hover:bg-green-600">Mulai Bermain</button>
<p id="input-error" class="text-red-500 text-sm mt-2 hidden text-center">Harap isi semua kolom!</p>
</div>
<!-- Tampilan 2: Permainan Perkalian -->
<div id="game-screen" class="hidden text-center space-y-6">
<!-- Teks Soal -->
<div class="bg-blue-500 text-white p-5 rounded-xl shadow-lg">
<p class="text-2xl font-medium mb-2">Soal Saat Ini:</p>
<div id="problem-text" class="text-6xl font-black">
<!-- Soal akan diisi di sini (e.g., 5 x 8 = ?) -->
</div>
</div>
<!-- Area Jawaban dan Tombol Cek -->
<div class="flex flex-col space-y-4">
<input type="number" id="answer-input" placeholder="Masukkan Jawaban" class="w-full p-4 text-center text-3xl border-4 border-green-400 rounded-xl focus:ring-green-500 focus:border-green-500 transition shadow-md font-mono" inputmode="numeric">
<button id="check-button" class="btn-primary w-full py-4 bg-blue-500 text-white font-extrabold rounded-xl text-2xl hover:bg-blue-600">CEK JAWABAN</button>
<p id="feedback-message" class="text-sm text-red-500 font-semibold hidden"></p>
</div>
<!-- Area Skor -->
<div class="p-3 bg-gray-100 rounded-xl border border-gray-300">
<p class="text-lg font-semibold text-gray-700">Skor Anda:</p>
<p id="score-display" class="text-4xl font-bold text-green-600">0</p>
</div>
</div>
</div>
<!-- Animasi Benar (Modal Overlay) -->
<div id="correct-overlay" class="fixed inset-0 bg-green-500/70 backdrop-blur-sm hidden items-center justify-center z-50 pointer-events-none">
<div id="correct-animation-emoji" class="text-9xl correct-animation transform scale-0" style="text-shadow: 0 0 20px rgba(0,0,0,0.5);">
😊
</div>
<div id="correct-animation-text" class="text-5xl font-black text-white absolute top-1/2 mt-32 correct-animation transform scale-0" style="text-shadow: 0 0 10px rgba(0,0,0,0.8);">
BENAR!
</div>
</div>
<script>
// Variabel Global
const APP_STATE = {
name: '',
school: '',
score: 0,
problem: { a: 0, b: 0, answer: 0 },
gameState: 'input', // 'input', 'playing'
isAnimating: false,
};
// DOM Element References
const inputScreen = document.getElementById('input-screen');
const gameScreen = document.getElementById('game-screen');
const startButton = document.getElementById('start-button');
const checkButton = document.getElementById('check-button');
const nameInput = document.getElementById('name-input');
const schoolInput = document.getElementById('school-input');
const inputError = document.getElementById('input-error');
const userInfoDisplay = document.getElementById('user-info');
const problemText = document.getElementById('problem-text');
const answerInput = document.getElementById('answer-input');
const scoreDisplay = document.getElementById('score-display');
const feedbackMessage = document.getElementById('feedback-message');
const correctOverlay = document.getElementById('correct-overlay');
const correctEmoji = document.getElementById('correct-animation-emoji');
const correctText = document.getElementById('correct-animation-text');
/**
* Mengubah tampilan UI berdasarkan state permainan.
*/
function renderUI() {
if (APP_STATE.gameState === 'input') {
inputScreen.classList.remove('hidden');
gameScreen.classList.add('hidden');
} else if (APP_STATE.gameState === 'playing') {
inputScreen.classList.add('hidden');
gameScreen.classList.remove('hidden');
// Update info dan skor
userInfoDisplay.textContent = `${APP_STATE.name} dari ${APP_STATE.school}`;
scoreDisplay.textContent = APP_STATE.score;
// Tampilkan soal baru
problemText.textContent = `${APP_STATE.problem.a} x ${APP_STATE.problem.b} = ?`;
// Atur fokus ke input jawaban
answerInput.value = '';
answerInput.focus();
}
}
/**
* Menghasilkan soal perkalian baru (angka 1 sampai 10).
*/
function generateProblem() {
const a = Math.floor(Math.random() * 10) + 1; // 1 to 10
const b = Math.floor(Math.random() * 10) + 1; // 1 to 10
APP_STATE.problem = { a, b, answer: a * b };
}
/**
* Menangani klik tombol Mulai Bermain.
*/
function handleStartGame() {
const nameValue = nameInput.value.trim();
const schoolValue = schoolInput.value.trim();
if (!nameValue || !schoolValue) {
inputError.classList.remove('hidden');
return;
}
inputError.classList.add('hidden');
APP_STATE.name = nameValue;
APP_STATE.school = schoolValue;
APP_STATE.gameState = 'playing';
// Siapkan soal pertama dan render UI
generateProblem();
renderUI();
}
/**
* Menampilkan animasi "Benar"
*/
function showCorrectAnimation() {
if (APP_STATE.isAnimating) return;
APP_STATE.isAnimating = true;
// Reset dan tampilkan overlay
correctEmoji.classList.remove('correct-animation');
correctText.classList.remove('correct-animation');
correctOverlay.classList.remove('hidden');
correctOverlay.classList.add('flex');
// Timeout singkat untuk memastikan reset animation class bekerja
setTimeout(() => {
correctEmoji.classList.add('correct-animation');
correctText.classList.add('correct-animation');
}, 50);
// Sembunyikan setelah 1 detik
setTimeout(() => {
correctOverlay.classList.remove('flex');
correctOverlay.classList.add('hidden');
APP_STATE.isAnimating = false;
}, 1000);
}
/**
* Menangani klik tombol Cek Jawaban.
*/
function handleCheckAnswer() {
const userAnswer = parseInt(answerInput.value.trim(), 10);
// Validasi input
if (isNaN(userAnswer)) {
feedbackMessage.textContent = "Jawaban harus berupa angka!";
feedbackMessage.classList.remove('hidden');
answerInput.focus();
return;
}
feedbackMessage.classList.add('hidden');
if (userAnswer === APP_STATE.problem.answer) {
// Jawaban Benar
APP_STATE.score += 1;
scoreDisplay.textContent = APP_STATE.score;
// Tampilkan animasi
showCorrectAnimation();
// Hasilkan soal baru setelah animasi
setTimeout(() => {
generateProblem();
renderUI(); // Render soal baru
}, 1000);
} else {
// Jawaban Salah
feedbackMessage.textContent = "Jawaban Salah! Coba lagi.";
feedbackMessage.classList.remove('hidden');
answerInput.focus();
answerInput.classList.add('border-red-500');
answerInput.classList.remove('border-green-400');
}
}
/**
* Menangani masukan dari keyboard (Enter).
*/
function handleKeydown(event) {
if (event.key === 'Enter') {
if (APP_STATE.gameState === 'input') {
handleStartGame();
} else if (APP_STATE.gameState === 'playing') {
handleCheckAnswer();
}
} else {
// Hapus highlight merah saat mulai mengetik lagi
answerInput.classList.remove('border-red-500');
answerInput.classList.add('border-green-400');
}
}
// --- Event Listeners ---
startButton.addEventListener('click', handleStartGame);
checkButton.addEventListener('click', handleCheckAnswer);
document.addEventListener('keydown', handleKeydown);
// --- Inisialisasi ---
document.addEventListener('DOMContentLoaded', () => {
renderUI();
});
</script>
</body>
</html>
Komentar
Posting Komentar