您只需要将下面的代码复制到一个文本文件中,将其命名为 whack-a-mole.html,然后用浏览器(特别是手机浏览器)打开即可开始游戏。
游戏预览
游戏特性
- 响应式设计: 自动适应手机屏幕尺寸。
- 触摸友好: 支持点击和触摸操作。
- 简单直观: 规则简单,一玩就懂。
- 计分系统: 实时显示得分和剩余时间。
- 本地存储: 游戏结束后会保存最高分。
HTML源码 (完整版)
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0, user-scalable=no">打地鼠 - 手机网页游戏</title>
<style>
/* 基础样式和重置 */
* {
margin: 0;
padding: 0;
box-sizing: border-box;
}
body {
font-family: 'Arial', sans-serif;
background: linear-gradient(to bottom, #87CEEB, #98D98E);
height: 100vh;
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
overflow: hidden; /* 防止页面滚动 */
touch-action: manipulation; /* 优化触摸响应 */
}
/* 游戏容器 */
.game-container {
width: 90vw; /* 视口宽度的90% */
max-width: 500px;
background-color: #8B4513;
border-radius: 20px;
padding: 20px;
box-shadow: 0 10px 30px rgba(0, 0, 0, 0.3);
}
/* 信息栏 */
.info-bar {
display: flex;
justify-content: space-between;
margin-bottom: 20px;
color: white;
font-size: 1.2em;
font-weight: bold;
}
/* 游戏板 */
.game-board {
display: grid;
grid-template-columns: repeat(3, 1fr);
grid-template-rows: repeat(3, 1fr);
gap: 15px;
aspect-ratio: 1 / 1; /* 保持正方形 */
}
/* 地洞 */
.hole {
position: relative;
width: 100%;
height: 100%;
background-color: #654321;
border-radius: 50%;
overflow: hidden;
cursor: pointer;
box-shadow: inset 0 5px 15px rgba(0, 0, 0, 0.5);
}
/* 地鼠 */
.mole {
position: absolute;
width: 80%;
height: 80%;
background-color: #8B4513;
border-radius: 50%;
top: 100%;
left: 50%;
transform: translateX(-50%);
transition: top 0.2s ease-in-out;
display: flex;
align-items: center;
justify-content: center;
font-size: 2em;
}
/* 地鼠出现 */
.mole.up {
top: 10%;
}
/* 游戏结束画面 */
.game-over {
position: fixed;
top: 0;
left: 0;
width: 100%;
height: 100%;
background-color: rgba(0, 0, 0, 0.8);
display: none;
flex-direction: column;
align-items: center;
justify-content: center;
color: white;
z-index: 1000;
}
.game-over h2 {
font-size: 2.5em;
margin-bottom: 20px;
}
.game-over p {
font-size: 1.5em;
margin-bottom: 30px;
}
.restart-btn {
padding: 15px 30px;
font-size: 1.2em;
background-color: #4CAF50;
color: white;
border: none;
border-radius: 10px;
cursor: pointer;
transition: background-color 0.3s;
}
.restart-btn:hover {
background-color: #45a049;
}
</style>
</head>
<body>
<div class="game-container">
<div class="info-bar">
<div>得分: <span id="score">0</span></div>
<div>时间: <span id="time">30</span>秒</div>
</div>
<div class="game-board" id="game-board">
<!-- 9个地洞将通过JavaScript动态生成 -->
</div>
</div>
<div class="game-over" id="game-over">
<h2>游戏结束!</h2>
<p>你的得分是: <span id="final-score">0</span></p>
<p>最高分是: <span id="high-score">0</span></p>
<button class="restart-btn" onclick="startGame()">再玩一次</button>
</div>
<script>
document.addEventListener('DOMContentLoaded', () => {
// 游戏状态
let score = 0;
let timeLeft = 30;
let gameActive = false;
let moleTimer = null;
let countdownTimer = null;
// DOM 元素
const gameBoard = document.getElementById('game-board');
const scoreElement = document.getElementById('score');
const timeElement = document.getElementById('time');
const gameOverScreen = document.getElementById('game-over');
const finalScoreElement = document.getElementById('final-score');
const highScoreElement = document.getElementById('high-score');
// 从本地存储加载最高分
let highScore = localStorage.getItem('whack-a-mole-high-score') || 0;
highScoreElement.textContent = highScore;
// 创建地洞和地鼠
function createBoard() {
for (let i = 0; i < 9; i++) {
const hole = document.createElement('div');
hole.classList.add('hole');
const mole = document.createElement('div');
mole.classList.add('mole');
mole.textContent = '🐹'; // 使用地鼠emoji
mole.id = `mole-${i}`;
hole.appendChild(mole);
gameBoard.appendChild(hole);
}
}
// 随机显示一个地鼠
function showRandomMole() {
if (!gameActive) return;
const moles = document.querySelectorAll('.mole');
const randomIndex = Math.floor(Math.random() * moles.length);
const randomMole = moles[randomIndex];
// 确保当前地鼠没有显示
if (!randomMole.classList.contains('up')) {
randomMole.classList.add('up');
// 随机时间后隐藏地鼠
const hideTime = Math.random() * 1000 + 500; // 0.5 到 1.5 秒
setTimeout(() => {
randomMole.classList.remove('up');
}, hideTime);
}
}
// 打地鼠事件
gameBoard.addEventListener('click', (e) => {
if (!gameActive) return;
const mole = e.target.closest('.mole');
if (mole && mole.classList.contains('up')) {
// 击中地鼠
mole.classList.remove('up');
score++;
scoreElement.textContent = score;
// 击中效果 (可以加一个动画或音效)
mole.style.transform = 'translateX(-50%) scale(0.8)';
setTimeout(() => {
mole.style.transform = 'translateX(-50%) scale(1)';
}, 100);
}
});
// 开始游戏
function startGame() {
// 重置游戏状态
score = 0;
timeLeft = 30;
gameActive = true;
scoreElement.textContent = score;
timeElement.textContent = timeLeft;
gameOverScreen.style.display = 'none';
// 清除之前的定时器
if (moleTimer) clearInterval(moleTimer);
if (countdownTimer) clearInterval(countdownTimer);
// 开始显示地鼠
moleTimer = setInterval(showRandomMole, 800); // 每0.8秒尝试显示一个地鼠
// 开始倒计时
countdownTimer = setInterval(() => {
timeLeft--;
timeElement.textContent = timeLeft;
if (timeLeft <= 0) {
endGame();
}
}, 1000);
}
// 结束游戏
function endGame() {
gameActive = false;
clearInterval(moleTimer);
clearInterval(countdownTimer);
// 隐藏所有地鼠
document.querySelectorAll('.mole').forEach(mole => {
mole.classList.remove('up');
});
// 更新并显示最高分
finalScoreElement.textContent = score;
if (score > highScore) {
highScore = score;
localStorage.setItem('whack-a-mole-high-score', highScore);
highScoreElement.textContent = highScore;
}
// 显示游戏结束画面
gameOverScreen.style.display = 'flex';
}
// 初始化游戏板
createBoard();
// 自动开始第一局游戏
startGame();
});
</script>
</body>
</html>
如何使用和运行
- 复制代码: 将上面所有的代码(从
<!DOCTYPE html>开始,到</html>结束)完整地复制下来。 - 创建文件: 在您的电脑上新建一个文本文档(.txt文件)。
- 粘贴并保存: 将复制的代码粘贴到这个文本文档中,然后将文件名修改为
whack-a-mole.html。注意:后缀名必须是.html。 - 打开游戏:
- 在电脑上: 直接用 Chrome、Firefox、Edge 等现代浏览器打开这个
whack-a-mole.html文件即可。 - 在手机上:
- 方法一 (推荐): 将这个HTML文件发送到您的手机上(例如通过微信、QQ、邮件附件等),然后在手机上用文件管理器找到它,用浏览器(如 Chrome, Safari, Firefox)打开。
- 方法二: 如果您的电脑和手机在同一个局域网内,您可以将这个HTML文件放到一个Web服务器(如 Python 的
http.server)上,然后在手机的浏览器中输入电脑的IP地址来访问。
- 在电脑上: 直接用 Chrome、Firefox、Edge 等现代浏览器打开这个
代码解析
-
HTML (骨架):
<meta name="viewport" ...>: 这行代码至关重要,它告诉浏览器如何控制页面的尺寸和缩放,user-scalable=no禁用了用户缩放,提供更佳的手机游戏体验。.game-container,.info-bar,.game-board: 这些是游戏的主要布局容器。.hole和.mole: 代表地洞和地鼠。.game-over: 游戏结束时显示的弹窗。
-
CSS (样式):
body: 设置了全屏、渐变背景,并使用flexbox将游戏内容居中。.game-board: 使用CSS Grid布局,轻松创建一个3x3的网格,aspect-ratio: 1 / 1确保它始终是正方形,在手机上看起来很协调。.mole:top: 100%让地鼠初始时藏在洞里。.mole.up类通过top: 10%将地鼠顶上来,transition属性让这个动作有平滑的动画效果。.game-over: 使用fixed定位,覆盖整个屏幕,半透明背景。
-
JavaScript (逻辑):
- 游戏初始化:
DOMContentLoaded事件确保在页面完全加载后才开始执行脚本。 - 动态创建:
createBoard()函数用循环创建了9个地洞和地鼠,避免了写大量重复的HTML代码。 - 核心逻辑:
showRandomMole(): 这是游戏的核心,它随机选择一个地鼠,给它加上up类让它显示出来,然后设置一个随机时间后移除up类让它隐藏。startGame(): 重置分数和时间,启动两个定时器——一个用于控制地鼠的出现频率,一个用于倒计时。endGame(): 停止所有定时器,隐藏所有地鼠,更新最高分,并显示游戏结束画面。
- 事件监听:
gameBoard.addEventListener('click', ...)监听整个游戏板的点击事件,当点击到地鼠并且地鼠是“up”状态时,就加分。 - 本地存储:
localStorage用于在浏览器中永久保存最高分,即使关闭页面再打开,最高分依然存在。
- 游戏初始化:
这份源码是一个很好的起点,您可以根据自己的喜好进行修改和扩展,比如添加音效、更复杂的动画、不同类型的敌人、道具系统等,希望您喜欢这个小游戏!
