这是一个基于HTML/CSS/JavaScript的打地鼠游戏网页代码。游戏包含以下功能:1) 12个地鼠洞随机弹出地鼠;2) 金色特殊地鼠提供更高分数;3) 可调节难度级别;4) 实时显示分数、时间和击中次数;5) 锤子跟随鼠标点击动画;6) 最高分记录保存;7) 游戏开始和结束菜单界面。游戏采用响应式设计,使用CSS动画和JavaScript定时器控制游戏逻辑,数据通过localStorage持久化存储最高分。
<!DOCTYPE html>
<html lang="en">
<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">
<style>
body {
display: flex;
flex-direction: column;
align-items: center;
background-color: #8B4513;
font-family: Arial, sans-serif;
margin: 0;
padding: 20px;
}
.game-container {
position: relative;
width: 800px;
}
.game-info {
display: flex;
justify-content: space-between;
width: 100%;
margin-bottom: 20px;
padding: 10px;
background-color: #5D3A1A;
color: white;
border-radius: 5px;
}
.holes-container {
display: grid;
grid-template-columns: repeat(4, 1fr);
gap: 20px;
}
.hole {
position: relative;
width: 180px;
height: 180px;
background-color: #5D3A1A;
border-radius: 50%;
overflow: hidden;
box-shadow: inset 0 10px 0 7px #3E2723,
inset 0 20px 20px 15px rgba(0, 0, 0, 0.3);
}
.mole {
position: absolute;
bottom: -100%;
left: 50%;
transform: translateX(-50%);
width: 120px;
height: 120px;
background-color: #A0522D;
border-radius: 50% 50% 40% 40%;
transition: bottom 0.3s ease;
cursor: pointer;
z-index: 2;
}
.mole.up {
bottom: 10px;
}
.mole.hit {
background-color: #CD5C5C;
animation: hit 0.3s;
}
@keyframes hit {
0% { transform: translateX(-50%) scale(1); }
50% { transform: translateX(-50%) scale(0.8); }
100% { transform: translateX(-50%) scale(1); }
}
.mole::before {
content: '';
position: absolute;
top: 30px;
left: 30px;
width: 15px;
height: 15px;
background-color: black;
border-radius: 50%;
}
.mole::after {
content: '';
position: absolute;
top: 30px;
right: 30px;
width: 15px;
height: 15px;
background-color: black;
border-radius: 50%;
}
.mole .nose {
position: absolute;
top: 50px;
left: 50%;
transform: translateX(-50%);
width: 20px;
height: 10px;
background-color: #000;
border-radius: 50%;
}
.mole .mouth {
position: absolute;
top: 70px;
left: 50%;
transform: translateX(-50%);
width: 30px;
height: 10px;
background-color: #000;
border-radius: 0 0 15px 15px;
}
.special-mole {
background-color: #FFD700;
}
.hole::after {
content: '';
position: absolute;
width: 100%;
height: 40px;
background-color: #8B4513;
bottom: 0;
z-index: 3;
border-top: 5px solid #5D3A1A;
}
.hammer {
position: fixed;
width: 80px;
height: 80px;
pointer-events: none;
z-index: 100;
opacity: 0;
transform-origin: bottom right;
transition: transform 0.1s, opacity 0.1s;
}
.hammer.active {
opacity: 1;
transform: rotate(-45deg);
}
.menu {
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
background-color: rgba(0, 0, 0, 0.8);
display: flex;
flex-direction: column;
justify-content: center;
align-items: center;
color: white;
z-index: 10;
border-radius: 5px;
}
button {
padding: 10px 20px;
font-size: 24px;
background-color: #F4A460;
color: #3E2723;
border: none;
border-radius: 5px;
cursor: pointer;
margin: 10px;
}
button:hover {
background-color: #CD853F;
}
.hidden {
display: none;
}
.difficulty-buttons {
display: flex;
margin: 20px 0;
}
.timer-bar {
height: 10px;
background-color: #4CAF50;
margin-top: 10px;
transition: width 1s linear;
}
.score-popup {
position: absolute;
color: #FFD700;
font-weight: bold;
pointer-events: none;
animation: floatUp 1s forwards;
}
@keyframes floatUp {
0% {
opacity: 1;
transform: translateY(0);
}
100% {
opacity: 0;
transform: translateY(-50px);
}
}
</style>
</head>
<body>
<h1 class="text-4xl mb-4 text-white">打地鼠游戏</h1>
<div class="game-container">
<div class="game-info">
<div>分数: <span id="score">0</span></div>
<div>时间: <span id="time">30</span>秒</div>
<div>击中: <span id="hits">0</span></div>
<div>最高分: <span id="highScore">0</span></div>
</div>
<div class="timer-bar-container">
<div class="timer-bar" id="timerBar"></div>
</div>
<div class="holes-container" id="holesContainer">
<!-- 地鼠洞将通过JS生成 -->
</div>
<!-- 锤子图标 -->
<div class="hammer" id="hammer">
<svg viewBox="0 0 100 100" xmlns="http://www.w3.org/2000/svg">
<rect x="60" y="10" width="15" height="70" fill="#8B4513"/>
<rect x="30" y="60" width="50" height="15" fill="#CD853F"/>
</svg>
</div>
<div class="menu" id="startMenu">
<h2 class="text-3xl mb-4">打地鼠</h2>
<p class="text-xl">点击冒出的地鼠得分</p>
<p class="text-xl">金色地鼠分数更高,但出现时间更短</p>
<p class="text-xl mt-4 mb-2">选择难度:</p>
<div class="difficulty-buttons">
<button data-time="60" data-speed="1500" class="difficulty-btn">简单</button>
<button data-time="45" data-speed="1000" class="difficulty-btn">中等</button>
<button data-time="30" data-speed="700" class="difficulty-btn">困难</button>
</div>
</div>
<div class="menu hidden" id="gameOverMenu">
<h2 class="text-3xl mb-2">游戏结束</h2>
<p class="text-xl mb-2">最终分数: <span id="finalScore">0</span></p>
<p class="text-xl mb-2">击中次数: <span id="finalHits">0</span></p>
<p class="text-xl mb-4">最高分: <span id="gameOverHighScore">0</span></p>
<button id="restartBtn">再来一次</button>
</div>
</div>
<script>
// 获取元素
const holesContainer = document.getElementById('holesContainer');
const scoreElement = document.getElementById('score');
const timeElement = document.getElementById('time');
const hitsElement = document.getElementById('hits');
const highScoreElement = document.getElementById('highScore');
const finalScoreElement = document.getElementById('finalScore');
const finalHitsElement = document.getElementById('finalHits');
const gameOverHighScoreElement = document.getElementById('gameOverHighScore');
const timerBarElement = document.getElementById('timerBar');
const hammerElement = document.getElementById('hammer');
const startMenu = document.getElementById('startMenu');
const gameOverMenu = document.getElementById('gameOverMenu');
const startBtn = document.getElementById('startBtn');
const restartBtn = document.getElementById('restartBtn');
const difficultyButtons = document.querySelectorAll('.difficulty-btn');
// 游戏常量
const HOLES_COUNT = 12;
const SPECIAL_MOLE_CHANCE = 0.2; // 20%几率出现特殊地鼠
const SPECIAL_MOLE_VALUE = 5; // 特殊地鼠分数
const NORMAL_MOLE_VALUE = 1; // 普通地鼠分数
// 游戏变量
let holes = [];
let moles = [];
let score = 0;
let hits = 0;
let gameTime = 30; // 秒
let currentTime = gameTime;
let moleSpeed = 1000; // 地鼠出现时间(毫秒)
let gameRunning = false;
let gameTimer;
let moleTimers = [];
let highScore = localStorage.getItem('whackHighScore') || 0;
// 初始化游戏
function initGame(time = 30, speed = 1000) {
// 设置游戏参数
gameTime = time;
currentTime = gameTime;
moleSpeed = speed;
// 重置游戏状态
score = 0;
hits = 0;
// 清空容器
holesContainer.innerHTML = '';
holes = [];
moles = [];
// 清除所有计时器
if (gameTimer) clearInterval(gameTimer);
moleTimers.forEach(timer => clearTimeout(timer));
moleTimers = [];
// 更新显示
scoreElement.textContent = score;
timeElement.textContent = currentTime;
hitsElement.textContent = hits;
timerBarElement.style.width = '100%';
// 生成地鼠洞
generateHoles();
// 显示开始菜单
startMenu.classList.remove('hidden');
gameOverMenu.classList.add('hidden');
gameRunning = false;
}
// 生成地鼠洞
function generateHoles() {
for (let i = 0; i < HOLES_COUNT; i++) {
// 创建地洞
const hole = document.createElement('div');
hole.className = 'hole';
hole.dataset.index = i;
// 创建地鼠
const mole = document.createElement('div');
mole.className = 'mole';
// 添加地鼠特征
const nose = document.createElement('div');
nose.className = 'nose';
mole.appendChild(nose);
const mouth = document.createElement('div');
mouth.className = 'mouth';
mole.appendChild(mouth);
// 添加点击事件
mole.addEventListener('click', () => hitMole(mole));
// 组装
hole.appendChild(mole);
holesContainer.appendChild(hole);
// 保存到数组
holes.push(hole);
moles.push(mole);
}
}
// 随机弹出地鼠
function popMole() {
if (!gameRunning) return;
// 选择随机地洞
const randomIndex = Math.floor(Math.random() * HOLES_COUNT);
const mole = moles[randomIndex];
// 如果地鼠已经弹出,重新选择
if (mole.classList.contains('up')) {
setTimeout(popMole, 100);
return;
}
// 随机决定是否是特殊地鼠
const isSpecial = Math.random() < SPECIAL_MOLE_CHANCE;
if (isSpecial) {
mole.classList.add('special-mole');
} else {
mole.classList.remove('special-mole');
}
// 弹出地鼠
mole.classList.add('up');
// 设置地鼠缩回的时间(特殊地鼠时间更短)
const duration = isSpecial ? moleSpeed * 0.6 : moleSpeed;
// 设置缩回计时器
const timer = setTimeout(() => {
mole.classList.remove('up', 'hit');
// 移除计时器引用
const index = moleTimers.indexOf(timer);
if (index !== -1) {
moleTimers.splice(index, 1);
}
}, duration);
moleTimers.push(timer);
// 设置下一个地鼠弹出的时间
const nextPopTime = 300 + Math.random() * 700;
setTimeout(popMole, nextPopTime);
}
// 击中地鼠
function hitMole(mole) {
if (!gameRunning || !mole.classList.contains('up') || mole.classList.contains('hit')) {
return;
}
// 显示击中效果
mole.classList.add('hit');
// 增加分数和击中次数
hits++;
hitsElement.textContent = hits;
// 判断是否是特殊地鼠
let points = NORMAL_MOLE_VALUE;
if (mole.classList.contains('special-mole')) {
points = SPECIAL_MOLE_VALUE;
}
score += points;
scoreElement.textContent = score;
// 显示分数弹出
showScorePopup(mole, points);
// 让地鼠缩回
setTimeout(() => {
mole.classList.remove('up', 'hit');
}, 300);
}
// 显示分数弹出
function showScorePopup(mole, points) {
const popup = document.createElement('div');
popup.className = 'score-popup';
popup.textContent = `+${points}`;
// 定位在鼠标点击位置
const rect = mole.getBoundingClientRect();
const gameRect = holesContainer.getBoundingClientRect();
popup.style.left = `${rect.left + rect.width / 2 - gameRect.left}px`;
popup.style.top = `${rect.top - gameRect.top}px`;
holesContainer.appendChild(popup);
// 动画结束后移除
setTimeout(() => {
popup.remove();
}, 1000);
}
// 更新游戏时间
function updateTime() {
if (gameRunning) {
currentTime--;
timeElement.textContent = currentTime;
// 更新时间条
const percentage = (currentTime / gameTime) * 100;
timerBarElement.style.width = `${percentage}%`;
// 时间到,游戏结束
if (currentTime <= 0) {
gameOver();
}
}
}
// 锤子动画
function animateHammer(e) {
if (!gameRunning) return;
// 定位锤子
hammerElement.style.left = `${e.clientX - 40}px`;
hammerElement.style.top = `${e.clientY - 40}px`;
// 显示锤子并添加动画
hammerElement.classList.add('active');
// 移除动画
setTimeout(() => {
hammerElement.classList.remove('active');
}, 100);
}
// 游戏结束
function gameOver() {
gameRunning = false;
clearInterval(gameTimer);
// 让所有地鼠缩回
moles.forEach(mole => {
mole.classList.remove('up', 'hit');
});
// 清除所有地鼠计时器
moleTimers.forEach(timer => clearTimeout(timer));
moleTimers = [];
// 更新最高分
if (score > highScore) {
highScore = score;
localStorage.setItem('whackHighScore', highScore);
highScoreElement.textContent = highScore;
}
// 显示游戏结束菜单
finalScoreElement.textContent = score;
finalHitsElement.textContent = hits;
gameOverHighScoreElement.textContent = highScore;
gameOverMenu.classList.remove('hidden');
}
// 开始游戏
function startGame(time, speed) {
startMenu.classList.add('hidden');
gameRunning = true;
// 开始计时
gameTimer = setInterval(updateTime, 1000);
// 开始弹出地鼠
setTimeout(popMole, 500);
}
// 事件监听
// 鼠标点击显示锤子动画
document.addEventListener('mousedown', animateHammer);
// 难度按钮
difficultyButtons.forEach(button => {
button.addEventListener('click', () => {
const time = parseInt(button.dataset.time);
const speed = parseInt(button.dataset.speed);
startGame(time, speed);
});
});
restartBtn.addEventListener('click', () => {
initGame(gameTime, moleSpeed);
});
// 初始化最高分显示
highScoreElement.textContent = highScore;
// 初始化游戏
initGame();
</script>
</body>
</html>
3万+

被折叠的 条评论
为什么被折叠?



