小游戏:基金会打地鼠
2025年8月1日
修订 9
评分
202
↑ 210
↓ 9
支持率
96%
总票数 219
Wilson 95% 下界
92.4%
在相同票数下更稳健的支持率估计
争议指数
0.158
评分趋势
按周聚合 加载图表中...
最近修订
1 / 4
最近投票
1 / 22
2025-09-17
2025-09-15
2025-09-13
2025-09-04
2025-09-04
2025-08-30
2025-08-30
2025-08-29
2025-08-28
2025-08-28
相关页面
暂无推荐
页面源码
[[include :scp-wiki-cn:credit:start]]
本页面由[[*user leather_boots]]与[[*user FATEfoggy]]合著,于中文分部最先发布,后翻译到基金会主站与国际站。
[[include :scp-wiki-cn:credit:end]]
这是一个网页小游戏,规则很简单。洞里面会出现Bright博士,你须要在有限的时间内尽量多地点击Bright博士,就像打地鼠游戏一样。
[[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">
<script>
tailwind.config = {
theme: {
extend: {
colors: {
primary: '#8B4513',
secondary: '#CD853F',
accent: '#FFA500',
dark: '#2D2A24',
},
fontFamily: {
game: ['"Comic Sans MS"', '"Marker Felt"', 'Arial', 'sans-serif'],
},
}
}
}
</script>
<style type="text/tailwindcss">
@layer utilities {
.content-auto {
content-visibility: auto;
}
.game-shadow {
box-shadow: 0 4px 8px rgba(0, 0, 0, 0.15);
}
.btn-hover {
transition: all 0.2s ease;
}
.btn-hover:hover {
transform: translateY(-2px);
box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1);
}
}
</style>
</head>
<body class="bg-gradient-to-br from-amber-50 to-orange-100 min-h-screen flex flex-col items-center justify-center p-4 font-game text-dark">
<audio id="hitSound" preload="auto">
<source src="http://scpsandboxcn.wikidot.com/local--files/balloon/hit_sound.wav" type="audio/wav">
</audio>
<div class="w-full max-w-2xl mx-auto">
<header class="text-center mb-4">
<h1 class="text-[clamp(1.5rem,4vw,2.5rem)] font-bold text-primary mb-1 tracking-tight">基金会打地鼠</h1>
<p class="text-gray-600 text-[clamp(0.9rem,1.5vw,1rem)]">在有限的时间内尽可能多地点击从洞里面跑出来的Bright博士</p>
</header>
<div class="game-container bg-secondary/30 rounded-xl p-3 md:p-4 game-shadow mb-4">
<div class="flex flex-wrap justify-between items-center mb-3">
<div class="flex items-center gap-1 bg-white/80 px-3 py-1 rounded-lg">
<i class="fa fa-clock-o text-primary text-lg"></i>
<span id="timer" class="text-xl font-bold">45</span>
<span class="text-sm ml-1">秒</span>
</div>
<div class="flex items-center gap-1 bg-white/80 px-3 py-1 rounded-lg">
<i class="fa fa-star text-accent text-lg"></i>
<span id="score" class="text-xl font-bold">0</span>
<span class="text-sm ml-1">分</span>
</div>
</div>
<div id="game-board" class="grid grid-cols-4 gap-1.5 md:gap-2 max-w-md mx-auto relative">
</div>
<div id="game-overlay" class="hidden absolute inset-0 bg-white/90 rounded-lg flex flex-col items-center justify-center z-20">
<!-- 通关图片(位于文字上方) -->
<img id="clear-image" src="https://scpsandboxcn.wdfiles.com/local--files/balloon/clear.png" alt="通关成功" class="mb-4 max-w-[200px] hidden">
<h2 id="final-score-overlay" class="text-2xl md:text-3xl font-bold text-primary mb-3"></h2>
<p id="score-rank-overlay" class="text-lg md:text-xl text-gray-700 mb-5"></p>
<button id="restart-btn-overlay" class="bg-primary hover:bg-primary/90 text-white text-lg md:text-xl font-bold py-2 px-6 rounded-full btn-hover shadow">
再来一局
</button>
</div>
<div id="failed-overlay" class="hidden absolute inset-0 bg-white/90 rounded-lg flex flex-col items-center justify-center z-20">
<!-- 失败图片(位于文字上方) -->
<img id="fail-image" src="https://scpsandboxcn.wdfiles.com/local--files/balloon/fail.png" alt="游戏失败" class="mb-4 max-w-[200px]">
<h2 class="text-2xl md:text-3xl font-bold text-red-600 mb-4">游戏失败</h2>
<p class="text-lg md:text-xl text-gray-700 mb-5">你点到SCP-096了</p>
<button id="try-again-btn-overlay" class="bg-primary hover:bg-primary/90 text-white text-lg md:text-xl font-bold py-2 px-6 rounded-full btn-hover shadow">
再试一次
</button>
</div>
</div>
<div id="start-screen" class="text-center py-6">
<button id="start-btn" class="bg-primary hover:bg-primary/90 text-white text-lg md:text-xl font-bold py-2 px-6 rounded-full btn-hover shadow">
开始游戏
</button>
</div>
</div>
<script>
document.addEventListener('DOMContentLoaded', () => {
const gameBoard = document.getElementById('game-board');
const startBtn = document.getElementById('start-btn');
const restartBtn = document.getElementById('restart-btn-overlay');
const tryAgainBtn = document.getElementById('try-again-btn-overlay');
const timerDisplay = document.getElementById('timer');
const scoreDisplay = document.getElementById('score');
const startScreen = document.getElementById('start-screen');
const gameOverlay = document.getElementById('game-overlay');
const failedOverlay = document.getElementById('failed-overlay');
const finalScoreDisplay = document.getElementById('final-score-overlay');
const scoreRankDisplay = document.getElementById('score-rank-overlay');
const clearImage = document.getElementById('clear-image'); // 通关图片元素
const EMPTY_HOLE = 'http://scpsandboxcn.wikidot.com/local--files/balloon/empty_hole.png';
const MOLE = 'https://scpsandboxcn.wdfiles.com/local--files/balloon/hole_with_jkb.png';
const HIT_MOLE = 'https://scpsandboxcn.wdfiles.com/local--files/balloon/hole_hit.png';
const BOMB = 'https://scpsandboxcn.wdfiles.com/local--files/balloon/96.png';
const GAME_OVER_IMG = 'https://scpsandboxcn.wikidot.com/local--files/balloon/gameover.png';
let score = 0;
let timer = 45;
let gameInterval;
let holes = [];
let bombHole = null;
const INITIAL_MOLES = 3;
const MAX_BOMBS = 1;
function createHoles() {
gameBoard.innerHTML = '';
holes = [];
for (let i = 0; i < 16; i++) {
const hole = document.createElement('div');
hole.className = 'aspect-square rounded-lg overflow-hidden relative cursor-pointer';
hole.dataset.id = i;
hole.dataset.state = 'empty';
const img = document.createElement('img');
img.src = EMPTY_HOLE;
img.alt = '空洞';
img.className = 'w-full h-full object-cover';
hole.appendChild(img);
gameBoard.appendChild(hole);
holes.push(hole);
hole.addEventListener('click', () => handleHoleClick(hole));
}
}
function startGame() {
score = 0;
timer = 45;
scoreDisplay.textContent = score;
timerDisplay.textContent = timer;
bombHole = null;
clearImage.classList.add('hidden'); // 隐藏通关图片
startScreen.classList.add('hidden');
gameOverlay.classList.add('hidden');
failedOverlay.classList.add('hidden');
gameBoard.classList.remove('hidden');
createHoles();
initializeMoles();
gameInterval = setInterval(() => {
timer--;
timerDisplay.textContent = timer;
if (timer === 0) {
endGame();
} else if ([25, 30, 35].includes(timer)) {
showBomb();
}
}, 1000);
}
function initializeMoles() {
let molesCreated = 0;
while (molesCreated < INITIAL_MOLES) {
const emptyHoles = holes.filter(hole => hole.dataset.state === 'empty');
if (emptyHoles.length === 0) break;
const randomHole = emptyHoles[Math.floor(Math.random() * emptyHoles.length)];
randomHole.dataset.state = 'mole';
randomHole.querySelector('img').src = MOLE;
randomHole.querySelector('img').alt = 'Bright博士';
molesCreated++;
}
}
function replaceMole() {
const emptyHoles = holes.filter(hole => hole.dataset.state === 'empty');
if (emptyHoles.length === 0) return;
const randomHole = emptyHoles[Math.floor(Math.random() * emptyHoles.length)];
randomHole.dataset.state = 'mole';
randomHole.querySelector('img').src = MOLE;
randomHole.querySelector('img').alt = 'Bright博士';
}
function getBombCount() {
return holes.filter(hole => hole.dataset.state === 'bomb').length;
}
function showBomb() {
if (getBombCount() >= MAX_BOMBS) return;
const availableHoles = holes.filter(hole =>
hole.dataset.state === 'empty' || hole.dataset.state === 'mole'
);
if (availableHoles.length === 0) return;
const randomHole = availableHoles[Math.floor(Math.random() * availableHoles.length)];
if (randomHole.dataset.state === 'mole') {
randomHole.dataset.state = 'empty';
randomHole.querySelector('img').src = EMPTY_HOLE;
randomHole.querySelector('img').alt = '空洞';
setTimeout(replaceMole, 0);
}
randomHole.dataset.state = 'bomb';
randomHole.querySelector('img').src = BOMB;
randomHole.querySelector('img').alt = 'SCP-096';
bombHole = randomHole;
setTimeout(() => {
if (bombHole && bombHole.dataset.state === 'bomb') {
bombHole.dataset.state = 'empty';
bombHole.querySelector('img').src = EMPTY_HOLE;
bombHole.querySelector('img').alt = '空洞';
bombHole = null;
}
}, 3000);
}
function handleHoleClick(hole) {
if (hole.dataset.state === 'mole') {
hitMole(hole);
} else if (hole.dataset.state === 'bomb') {
hitBomb(hole);
}
}
function hitMole(hole) {
const hitSound = document.getElementById('hitSound');
hitSound.currentTime = 0;
hitSound.play().catch(e => console.log('音效播放失败:', e));
hole.dataset.state = 'hit';
hole.querySelector('img').src = HIT_MOLE;
hole.querySelector('img').alt = '被击中的Bright博士';
score++;
scoreDisplay.textContent = score;
setTimeout(() => {
hole.dataset.state = 'empty';
hole.querySelector('img').src = EMPTY_HOLE;
hole.querySelector('img').alt = '空洞';
replaceMole();
}, 500);
}
function hitBomb(hole) {
hole.dataset.state = 'hitBomb';
clearInterval(gameInterval);
setTimeout(() => {
failedOverlay.classList.remove('hidden');
}, 500);
}
function endGame() {
clearInterval(gameInterval);
holes.forEach(hole => {
hole.removeEventListener('click', handleHoleClick);
});
// 当分数大于20分时显示通关图片
if (score > 20) {
clearImage.classList.remove('hidden');
} else {
clearImage.classList.add('hidden');
}
finalScoreDisplay.textContent = `最终得分: ${score}`;
let rankText;
if (score == 0) rankText = '您似乎不会操作,或者设备出故障了。';
else if (score <= 30) rankText = '您的成绩超过了4%的D级人员。';
else if (score <= 45) rankText = '您的成绩超过了46%的D级人员。';
else if (score <= 55) rankText = '您的成绩超过了61%的D级人员。';
else if (score <= 65) rankText = '您的成绩超过了78%的D级人员。';
else if (score <= 75) rankText = '您的成绩超过了84%的D级人员。';
else if (score <= 80) rankText = '您的成绩超过了92%的D级人员。';
else if (score <= 85) rankText = '您的成绩超过了64%的研究员。';
else if (score <= 90) rankText = '您的成绩超过了87%的研究员。';
else if (score <= 95) rankText = '您的成绩超过了93%的研究员。';
else if (score <= 100) rankText = '您的成绩超过了96%的研究员。';
else if (score <= 105) rankText = '您的成绩超过了98%的研究员。';
else if (score <= 110) rankText = '您的成绩超过了43%的站点主管。';
else if (score <= 115) rankText = '您的成绩超过了65%的站点主管。';
else if (score <= 120) rankText = '您的成绩超过了77%的站点主管。';
else if (score <= 125) rankText = '您的成绩超过了89%的站点主管。';
else if (score <= 130) rankText = '您的成绩超过了71%的O5议会成员。';
else if (score <= 135) rankText = '您的成绩超过了88%的O5议会成员。';
else if (score <= 145) rankText = '您的成绩超过了96%的O5议会成员。';
else if (score <= 180) rankText = '您的成绩超过了100%的O5议会成员。恭喜。';
else rankText = '您开连点器了,对吧?';
scoreRankDisplay.textContent = rankText;
gameOverlay.classList.remove('hidden');
}
startBtn.addEventListener('click', startGame);
restartBtn.addEventListener('click', startGame);
tryAgainBtn.addEventListener('click', startGame);
});
</script>
</body>
</html>
[[/html]]
------
游戏界面需要加载后才会在上方显示,这大概需要20秒时间。如果游戏出现显示问题或者加载失败可以刷新网页。第一次运行游戏可能比较卡顿,运行一会就会变流畅。
负责本页面程序的是[[*user leather_boots]],负责本页面美术的是[[*user FATEfoggy]]。任何关于本页面的想法都欢迎在讨论区反馈,我们会认真阅读每一条讨论帖 :)