在当今数字化时代,小游戏不仅是娱乐的载体,更是学习编程的绝佳实践项目。今天,我将和大家分享一个简单而有趣的数学计算小游戏的开发过程,这个游戏主要运用了 HTML、CSS 和 JavaScript 技术。
一、项目概述
二、HTML 搭建结构
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>数学计算小游戏</title>
<script src="https://cdn.tailwindcss.com"></script>
<link href="https://cdn.jsdelivr.net/npm/font-awesome@4.7.0/css/font-awesome.min.css" rel="stylesheet">
<!-- 其他头部代码 -->
</head>
<header class="text-center mb-8">
<h1 class="text-[clamp(2rem,5vw,3.5rem)] font-bold text-primary mb-2 text-shadow">
<i class="fa fa-calculator mr-3"></i>数学计算小游戏
</h1>
<p class="text-neutral text-lg">锻炼你的心算能力,挑战自我!</p>
</header>
<div id="settings" class="space-y-6 mb-8">
<h2 class="text-2xl font-semibold text-primary mb-4">游戏设置</h2>
<!-- 难度选择 -->
<div class="space-y-3">
<label class="block text-lg font-medium text-neutral">选择难度</label>
<div class="grid grid-cols-1 md:grid-cols-2 gap-4">
<button id="easy" class="flex items-center justify-center p-4 bg-blue-50 border-2 border-primary rounded-xl text-primary font-medium btn-hover">
<i class="fa fa-check-circle mr-2"></i> 10以内
</button>
<button id="hard" class="flex items-center justify-center p-4 bg-gray-50 border-2 border-gray-200 rounded-xl text-gray-500 font-medium btn-hover">
<i class="fa fa-circle-o mr-2"></i> 100以内
</button>
</div>
</div>
<!-- 运算类型选择 -->
<div class="space-y-3">
<label class="block text-lg font-medium text-neutral">选择运算类型</label>
<div class="grid grid-cols-1 md:grid-cols-2 gap-4">
<button id="add-subtract" class="flex items-center justify-center p-4 bg-blue-50 border-2 border-primary rounded-xl text-primary font-medium btn-hover">
<i class="fa fa-check-circle mr-2"></i> 加减法
</button>
<button id="multiply-divide" class="flex items-center justify-center p-4 bg-gray-50 border-2 border-gray-200 rounded-xl text-gray-500 font-medium btn-hover">
<i class="fa fa-circle-o mr-2"></i> 乘除法
</button>
</div>
</div>
<!-- 开始游戏按钮 -->
<button id="start-game" class="w-full py-4 bg-primary text-white rounded-xl text-lg font-semibold shadow-lg hover:bg-primary/90 transition-all duration-300 btn-hover">
开始游戏 <i class="fa fa-play ml-2"></i>
</button>
</div>
<div id="game-content" class="hidden">
<!-- 游戏进度和得分 -->
<div class="flex justify-between items-center mb-6">
<div class="text-neutral">
<span class="font-medium">当前进度:</span>
<span id="progress">1/10</span>
</div>
<div class="text-neutral">
<span class="font-medium">得分:</span>
<span id="score" class="text-secondary">0</span>
</div>
</div>
<!-- 题目区域 -->
<div class="bg-gray-50 rounded-xl p-8 mb-6 text-center">
<h3 class="text-lg font-medium text-neutral mb-4">请计算:</h3>
<div id="question" class="text-[clamp(1.5rem,4vw,2.5rem)] font-bold text-primary mb-6">5 + 3 = ?</div>
<!-- 输入答案 -->
<div class="max-w-xs mx-auto">
<input type="number" id="answer" class="w-full p-4 border-2 border-gray-200 rounded-xl text-center text-xl focus:outline-none focus:border-primary transition-all" placeholder="输入你的答案">
<button id="submit-answer" class="w-full mt-4 py-3 bg-secondary text-white rounded-xl font-medium shadow-lg hover:bg-secondary/90 transition-all duration-300 btn-hover">
提交答案 <i class="fa fa-paper-plane ml-2"></i>
</button>
</div>
</div>
<!-- 反馈区域 -->
<div id="feedback" class="hidden p-4 rounded-xl mb-6 text-center"></div>
<!-- 下一题按钮 -->
<button id="next-question" class="hidden w-full py-3 bg-primary text-white rounded-xl font-medium shadow-lg hover:bg-primary/90 transition-all duration-300 btn-hover">
下一题 <i class="fa fa-arrow-right ml-2"></i>
</button>
</div>
<div id="game-over" class="hidden text-center">
<div class="bg-gray-50 rounded-xl p-8 mb-6">
<h3 class="text-2xl font-bold text-primary mb-2">游戏结束!</h3>
<p class="text-lg text-neutral mb-4">恭喜你完成了所有题目</p>
<div class="text-4xl font-bold text-secondary mb-6">
得分: <span id="final-score">0</span>
</div>
<div class="flex justify-center space-x-4">
<button id="play-again" class="px-6 py-3 bg-primary text-white rounded-xl font-medium shadow-lg hover:bg-primary/90 transition-all duration-300 btn-hover">
再玩一次 <i class="fa fa-refresh ml-2"></i>
</button>
<button id="change-settings" class="px-6 py-3 bg-gray-200 text-neutral rounded-xl font-medium hover:bg-gray-300 transition-all duration-300 btn-hover">
更改设置 <i class="fa fa-cog ml-2"></i>
</button>
</div>
</div>
<!-- 游戏统计 -->
<div class="grid grid-cols-2 gap-4 mb-6">
<div class="bg-blue-50 rounded-xl p-4">
<div class="text-blue-600 text-sm font-medium mb-1">正确题数</div>
<div class="text-2xl font-bold text-blue-600" id="correct-count">0</div>
</div>
<div class="bg-red-50 rounded-xl p-4">
<div class="text-red-600 text-sm font-medium mb-1">错误题数</div>
<div class="text-2xl font-bold text-red-600" id="wrong-count">0</div>
</div>
</div>
</div>
三、CSS 美化界面
tailwind.config = {
theme: {
extend: {
colors: {
primary: '#4F46E5',
secondary: '#10B981',
accent: '#F59E0B',
danger: '#EF4444',
neutral: '#6B7280',
},
fontFamily: {
inter: ['Inter', 'sans-serif'],
},
}
}
}
@layer utilities {
.content-auto {
content-visibility: auto;
}
.text-shadow {
text-shadow: 0 2px 4px rgba(0,0,0,0.1);
}
.card-shadow {
box-shadow: 0 10px 15px -3px rgba(0, 0, 0, 0.1), 0 4px 6px -2px rgba(0, 0, 0, 0.05);
}
.btn-hover {
transition: all 0.3s ease;
}
.btn-hover:hover {
transform: translateY(-2px);
}
}
四、JavaScript 实现交互逻辑
const gameConfig = {
difficulty: 'easy', // 'easy' 或 'hard'
operation: 'add-subtract', // 'add-subtract' 或 'multiply-divide'
currentQuestion: 0,
totalQuestions: 10,
score: 0,
correctAnswers: 0,
wrongAnswers: 0,
currentProblem: {
num1: 0,
num2: 0,
operator: '+',
answer: 0
}
};
// 事件监听器 - 难度选择
easyBtn.addEventListener('click', () => {
selectDifficulty('easy');
});
hardBtn.addEventListener('click', () => {
selectDifficulty('hard');
});
// 事件监听器 - 运算类型选择
addSubtractBtn.addEventListener('click', () => {
selectOperation('add-subtract');
});
multiplyDivideBtn.addEventListener('click', () => {
selectOperation('multiply-divide');
});
// 事件监听器 - 开始游戏
startGameBtn.addEventListener('click', startGame);
// 事件监听器 - 提交答案
submitAnswerBtn.addEventListener('click', checkAnswer);
answerInput.addEventListener('keypress', (e) => {
if (e.key === 'Enter') {
checkAnswer();
}
});
// 事件监听器 - 下一题
nextQuestionBtn.addEventListener('click', nextQuestion);
// 事件监听器 - 游戏结束后
playAgainBtn.addEventListener('click', () => {
resetGame(false);
});
changeSettingsBtn.addEventListener('click', () => {
resetGame(true);
});
// 选择难度
function selectDifficulty(difficulty) {
gameConfig.difficulty = difficulty;
// 更新UI
if (difficulty === 'easy') {
easyBtn.classList.remove('bg-gray-50', 'border-gray-200', 'text-gray-500');
easyBtn.classList.add('bg-blue-50', 'border-primary', 'text-primary');
easyBtn.innerHTML = '<i class="fa fa-check-circle mr-2"></i> 10以内';
hardBtn.classList.remove('bg-blue-50', 'border-primary', 'text-primary');
hardBtn.classList.add('bg-gray-50', 'border-gray-200', 'text-gray-500');
hardBtn.innerHTML = '<i class="fa fa-circle-o mr-2"></i> 100以内';
} else {
hardBtn.classList.remove('bg-gray-50', 'border-gray-200', 'text-gray-500');
hardBtn.classList.add('bg-blue-50', 'border-primary', 'text-primary');
hardBtn.innerHTML = '<i class="fa fa-check-circle mr-2"></i> 100以内';
easyBtn.classList.remove('bg-blue-50', 'border-primary', 'text-primary');
easyBtn.classList.add('bg-gray-50', 'border-gray-200', 'text-gray-500');
easyBtn.innerHTML = '<i class="fa fa-circle-o mr-2"></i> 10以内';
}
}
// 选择运算类型
function selectOperation(operation) {
gameConfig.operation = operation;
// 更新UI
if (operation === 'add-subtract') {
addSubtractBtn.classList.remove('bg-gray-50', 'border-gray-200', 'text-gray-500');
addSubtractBtn.classList.add('bg-blue-50', 'border-primary', 'text-primary');
addSubtractBtn.innerHTML = '<i class="fa fa-check-circle mr-2"></i> 加减法';
multiplyDivideBtn.classList.remove('bg-blue-50', 'border-primary', 'text-primary');
multiplyDivideBtn.classList.add('bg-gray-50', 'border-gray-200', 'text-gray-500');
multiplyDivideBtn.innerHTML = '<i class="fa fa-circle-o mr-2"></i> 乘除法';
} else {
multiplyDivideBtn.classList.remove('bg-gray-50', 'border-gray-200', 'text-gray-500');
multiplyDivideBtn.classList.add('bg-blue-50', 'border-primary', 'text-primary');
multiplyDivideBtn.innerHTML = '<i class="fa fa-check-circle mr-2"></i> 乘除法';
addSubtractBtn.classList.remove('bg-blue-50', 'border-primary', 'text-primary');
addSubtractBtn.classList.add('bg-gray-50', 'border-gray-200', 'text-gray-500');
addSubtractBtn.innerHTML = '<i class="fa fa-circle-o mr-2"></i> 加减法';
}
}
// 开始游戏
function startGame() {
// 重置游戏状态
gameConfig.currentQuestion = 1;
gameConfig.score = 0;
gameConfig.correctAnswers = 0;
gameConfig.wrongAnswers = 0;
// 更新UI
settingsSection.classList.add('hidden');
gameContentSection.classList.remove('hidden');
gameOverSection.classList.add('hidden');
// 生成第一个问题
generateQuestion();
updateProgress();
updateScore();
}
// 生成问题
function generateQuestion() {
const maxNumber = gameConfig.difficulty === 'easy' ? 10 : 100;
let operators = [];
// 根据选择的运算类型确定操作符
if (gameConfig.operation === 'add-subtract') {
operators = ['+', '-'];
} else {
operators = ['×', '÷'];
}
// 随机选择操作符
const operator = operators[Math.floor(Math.random() * operators.length)];
let num1, num2, answer;
// 根据操作符生成适当的数字
if (operator === '+') {
// 加法:确保结果不超过最大值
num2 = Math.floor(Math.random() * maxNumber) + 1;
num1 = Math.floor(Math.random() * (maxNumber - num2 + 1)) + 1;
answer = num1 + num2;
} else if (operator === '-') {
// 减法:确保结果为正数
num1 = Math.floor(Math.random() * maxNumber) + 1;
num2 = Math.floor(Math.random() * num1) + 1;
answer = num1 - num2;
} else if (operator === '×') {
// 乘法:限制数字大小,避免结果过大
const maxMultiplier = gameConfig.difficulty === 'easy' ? 5 : 10;
num1 = Math.floor(Math.random() * maxMultiplier) + 1;
num2 = Math.floor(Math.random() * maxMultiplier) + 1;
answer = num1 * num2;
} else if (operator === '÷') {
// 除法:确保结果为整数
answer = Math.floor(Math.random() * maxNumber) + 1;
num2 = Math.floor(Math.random() * 9) + 1; // 除数为1-9
num1 = answer * num2;
}
// 保存当前问题
gameConfig.currentProblem = {
num1,
num2,
operator,
answer
};
// 更新问题显示
questionEl.textContent = `${num1} ${operator} ${num2} = ?`;
// 重置输入和反馈
answerInput.value = '';
answerInput.focus();
feedbackEl.classList.add('hidden');
nextQuestionBtn.classList.add('hidden');
submitAnswerBtn.classList.remove('hidden');
}
// 检查答案
function checkAnswer() {
const userAnswer = parseInt(answerInput.value, 10);
// 验证输入
if (isNaN(userAnswer)) {
showFeedback('请输入有效的数字!', 'error');
return;
}
// 检查答案是否正确
if (userAnswer === gameConfig.currentProblem.answer) {
gameConfig.score += 10;
gameConfig.correctAnswers++;
showFeedback('🎉 恭喜,答对了!', 'correct');
} else {
gameConfig.wrongAnswers++;
showFeedback(`❌ 答错了,正确答案是 ${gameConfig.currentProblem.answer}`, 'wrong');
}
// 更新UI
updateScore();
// 检查游戏是否结束
if (gameConfig.currentQuestion >= gameConfig.totalQuestions) {
submitAnswerBtn.classList.add('hidden');
nextQuestionBtn.textContent = '查看结果';
nextQuestionBtn.onclick = showGameOver;
}
nextQuestionBtn.classList.remove('hidden');
submitAnswerBtn.classList.add('hidden');
}
// 显示反馈
function showFeedback(message, type) {
feedbackEl.textContent = message;
feedbackEl.classList.remove('hidden', 'bg-green-50', 'text-green-600', 'bg-red-50', 'text-red-600');
if (type === 'correct') {
feedbackEl.classList.add('bg-green-50', 'text-green-600');
} else if (type === 'wrong') {
feedbackEl.classList.add('bg-red-50', 'text-red-600');
} else {
feedbackEl.classList.add('bg-yellow-50', 'text-yellow-600');
}
}
// 下一题
function nextQuestion() {
gameConfig.currentQuestion++;
updateProgress();
generateQuestion();
}
// 更新进度
function updateProgress() {
progressEl.textContent = `${gameConfig.currentQuestion}/${gameConfig.totalQuestions}`;
}
// 更新分数
function updateScore() {
scoreEl.textContent = gameConfig.score;
}
// 显示游戏结束
function showGameOver() {
gameContentSection.classList.add('hidden');
gameOverSection.classList.remove('hidden');
// 更新游戏结束统计
finalScoreEl.textContent = gameConfig.score;
correctCountEl.textContent = gameConfig.correctAnswers;
wrongCountEl.textContent = gameConfig.wrongAnswers;
}
// 重置游戏
function resetGame(showSettings) {
if (showSettings) {
gameOverSection.classList.add('hidden');
settingsSection.classList.remove('hidden');
} else {
gameOverSection.classList.add('hidden');
gameConfig.currentQuestion = 1;
gameConfig.score = 0;
gameConfig.correctAnswers = 0;
gameConfig.wrongAnswers = 0;
updateProgress();
updateScore();
gameContentSection.classList.remove('hidden');
generateQuestion();
}
}