上班石板煎薯饼
const gameTest = `
<!DOCTYPE html>
<html>
<head>
<title>测试版-石板煎薯饼</title>
<style>
body { font-family: Arial; padding: 20px; text-align: center; }
.game { margin: 20px auto; width: 300px; padding: 20px; border: 2px solid #333; border-radius: 10px; }
button { margin: 10px; padding: 10px 20px; font-size: 16px; }
#potato { width: 100px; height: 100px; background: gold; border-radius: 50%; margin: 20px auto; }
</style>
</head>
<body>
<h2>石板煎薯饼 - 测试版</h2>
<div class="game">
<div id="potato"></div>
<div>状态: <span id="status">准备中</span></div>
<button onclick="start()">开始煎制</button>
<button onclick="flip()">翻面</button>
</div>
<script>
let state = 'raw';
function start() {
state = 'cooking';
document.getElementById('potato').style.background = 'orange';
document.getElementById('status').textContent = '煎制中';
}
function flip() {
state = 'flipped';
document.getElementById('potato').style.background = 'brown';
document.getElementById('status').textContent = '已翻面';
}
</script>
</body>
</html>
`;
const testWindow = window.open();
testWindow.document.write(gameTest);
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>上班石板煎薯饼</title>
<style>
* {
margin: 0;
padding: 0;
box-sizing: border-box;
font-family: 'Segoe UI', 'Microsoft YaHei', sans-serif;
}
body {
background-color: #f5f5f5;
display: flex;
justify-content: center;
align-items: center;
min-height: 100vh;
padding: 20px;
}
.game-container {
width: 100%;
max-width: 800px;
background-color: #fff;
border-radius: 15px;
box-shadow: 0 10px 30px rgba(0, 0, 0, 0.1);
overflow: hidden;
}
.header {
background: linear-gradient(to right, #4b6cb7, #182848);
color: white;
padding: 20px;
text-align: center;
}
.header h1 {
font-size: 28px;
margin-bottom: 8px;
}
.header p {
opacity: 0.9;
}
.game-area {
padding: 25px;
display: flex;
flex-direction: column;
align-items: center;
}
.stats-bar {
display: flex;
justify-content: space-between;
width: 100%;
margin-bottom: 25px;
background-color: #f9f9f9;
padding: 15px;
border-radius: 10px;
border: 1px solid #eaeaea;
}
.stat-item {
text-align: center;
flex: 1;
}
.stat-label {
font-size: 14px;
color: #666;
margin-bottom: 5px;
}
.stat-value {
font-size: 24px;
font-weight: bold;
color: #4b6cb7;
}
.game-scene {
width: 100%;
height: 400px;
background-color: #e8f4f8;
border-radius: 10px;
position: relative;
overflow: hidden;
border: 2px solid #ddd;
margin-bottom: 20px;
}
.desk {
position: absolute;
bottom: 0;
width: 100%;
height: 40%;
background-color: #8B4513;
border-top: 5px solid #A0522D;
}
.stone-slab {
position: absolute;
width: 200px;
height: 120px;
background-color: #808080;
border-radius: 8px;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
box-shadow: inset 0 0 15px rgba(0, 0, 0, 0.5);
display: flex;
justify-content: center;
align-items: center;
}
.potato-cake {
width: 100px;
height: 100px;
border-radius: 50%;
position: relative;
cursor: pointer;
transition: transform 0.3s;
}
.potato-cake:hover {
transform: scale(1.05);
}
.potato-cake.raw {
background-color: #f0e68c;
border: 3px solid #d2b48c;
}
.potato-cake.cooking {
background-color: #ffa500;
border: 3px solid #ff8c00;
}
.potato-cake.perfect {
background-color: #daa520;
border: 3px solid #b8860b;
box-shadow: 0 0 15px gold;
}
.potato-cake.burnt {
background-color: #8b4513;
border: 3px solid #654321;
}
.boss {
position: absolute;
width: 60px;
height: 100px;
top: 20px;
right: -70px;
transition: right 0.5s;
z-index: 10;
}
.boss.active {
right: 20px;
}
.boss-head {
width: 50px;
height: 50px;
background-color: #333;
border-radius: 50%;
position: absolute;
top: 0;
left: 5px;
}
.boss-body {
width: 40px;
height: 40px;
background-color: #444;
position: absolute;
top: 45px;
left: 10px;
border-radius: 10px 10px 0 0;
}
.controls {
display: flex;
gap: 15px;
margin-top: 10px;
}
button {
padding: 12px 25px;
font-size: 16px;
border: none;
border-radius: 8px;
cursor: pointer;
font-weight: bold;
transition: all 0.3s;
}
#start-btn {
background-color: #4CAF50;
color: white;
}
#start-btn:hover {
background-color: #45a049;
}
#flip-btn {
background-color: #2196F3;
color: white;
}
#flip-btn:hover {
background-color: #0b7dda;
}
#reset-btn {
background-color: #f44336;
color: white;
}
#reset-btn:hover {
background-color: #da190b;
}
.instructions {
background-color: #f9f9f9;
padding: 20px;
border-radius: 10px;
margin-top: 25px;
font-size: 15px;
line-height: 1.5;
border-left: 5px solid #4b6cb7;
}
.instructions h3 {
color: #182848;
margin-bottom: 10px;
}
.instructions ul {
padding-left: 20px;
}
.instructions li {
margin-bottom: 8px;
}
.message {
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
background-color: rgba(0, 0, 0, 0.8);
color: white;
padding: 15px 30px;
border-radius: 10px;
font-size: 24px;
font-weight: bold;
text-align: center;
z-index: 100;
display: none;
}
.cooking-time {
position: absolute;
top: 10px;
left: 10px;
background-color: rgba(0, 0, 0, 0.7);
color: white;
padding: 5px 10px;
border-radius: 5px;
font-size: 14px;
}
.status-indicator {
position: absolute;
top: 10px;
right: 10px;
background-color: rgba(0, 0, 0, 0.7);
color: white;
padding: 5px 10px;
border-radius: 5px;
font-size: 14px;
}
@media (max-width: 600px) {
.game-scene {
height: 300px;
}
.stats-bar {
flex-direction: column;
gap: 15px;
}
.controls {
flex-wrap: wrap;
justify-content: center;
}
}
</style>
</head>
<body>
<div class="game-container">
<div class="header">
<h1>上班石板煎薯饼</h1>
<p>在老板巡视间隙煎出完美薯饼,小心别被发现了!</p>
</div>
<div class="game-area">
<div class="stats-bar">
<div class="stat-item">
<div class="stat-label">煎制数量</div>
<div id="cooked-count" class="stat-value">0</div>
</div>
<div class="stat-item">
<div class="stat-label">完美薯饼</div>
<div id="perfect-count" class="stat-value">0</div>
</div>
<div class="stat-item">
<div class="stat-label">老板警觉度</div>
<div id="boss-alert" class="stat-value">0%</div>
</div>
</div>
<div class="game-scene">
<div class="desk"></div>
<div class="stone-slab">
<div id="potato-cake" class="potato-cake raw"></div>
</div>
<div class="boss" id="boss">
<div class="boss-head"></div>
<div class="boss-body"></div>
</div>
<div id="cooking-time" class="cooking-time">煎制时间: 0s</div>
<div id="status-indicator" class="status-indicator">状态: 生的</div>
<div id="message" class="message"></div>
</div>
<div class="controls">
<button id="start-btn">开始煎制</button>
<button id="flip-btn" disabled>翻面</button>
<button id="reset-btn">重置游戏</button>
</div>
<div class="instructions">
<h3>游戏说明</h3>
<ul>
<li><strong>目标</strong>: 在老板巡视的间隙,煎出尽可能多的完美薯饼</li>
<li><strong>玩法</strong>: 点击"开始煎制"开始烹饪薯饼,当薯饼变为金黄色时点击"翻面",两面都煎到完美状态即可得分</li>
<li><strong>注意</strong>: 老板会不定期巡视,如果发现你在煎薯饼,老板警觉度会上升,达到100%游戏结束</li>
<li><strong>提示</strong>: 薯饼状态: 生的 → 煎制中 → 完美 → 煎糊。在完美状态时翻面或取出可得高分!</li>
</ul>
</div>
</div>
</div>
<script>
let gameActive = false;
let cookingTime = 0;
let cookingInterval;
let potatoState = 'raw';
let side = 1;
let cookedCount = 0;
let perfectCount = 0;
let bossAlert = 0;
let bossInterval;
let bossActive = false;
let bossTimer;
const potatoCake = document.getElementById('potato-cake');
const startBtn = document.getElementById('start-btn');
const flipBtn = document.getElementById('flip-btn');
const resetBtn = document.getElementById('reset-btn');
const cookedCountEl = document.getElementById('cooked-count');
const perfectCountEl = document.getElementById('perfect-count');
const bossAlertEl = document.getElementById('boss-alert');
const cookingTimeEl = document.getElementById('cooking-time');
const statusIndicator = document.getElementById('status-indicator');
const messageEl = document.getElementById('message');
const bossEl = document.getElementById('boss');
function initGame() {
gameActive = false;
cookingTime = 0;
potatoState = 'raw';
side = 1;
bossAlert = 0;
updatePotatoAppearance();
updateUI();
clearIntervals();
startBtn.disabled = false;
flipBtn.disabled = true;
showMessage("点击'开始煎制'开始游戏", 3000);
}
function startCooking() {
if (gameActive) return;
gameActive = true;
startBtn.disabled = true;
flipBtn.disabled = false;
potatoState = 'cooking';
cookingInterval = setInterval(() => {
cookingTime++;
updatePotatoState();
updateUI();
}, 1000);
bossInterval = setInterval(() => {
if (Math.random() < 0.3 && !bossActive) {
startBossCheck();
}
}, 3000);
showMessage("薯饼正在煎制中,注意观察颜色变化!", 2000);
}
function updatePotatoState() {
if (side === 1) {
if (cookingTime <= 3) {
potatoState = 'cooking';
} else if (cookingTime <= 6) {
potatoState = 'perfect';
} else {
potatoState = 'burnt';
}
} else {
if (cookingTime <= 2) {
potatoState = 'cooking';
} else if (cookingTime <= 4) {
potatoState = 'perfect';
} else {
potatoState = 'burnt';
}
}
updatePotatoAppearance();
}
function updatePotatoAppearance() {
potatoCake.className = 'potato-cake ' + potatoState;
let statusText = '';
switch(potatoState) {
case 'raw': statusText = '生的'; break;
case 'cooking': statusText = '煎制中'; break;
case 'perfect': statusText = '完美'; break;
case 'burnt': statusText = '煎糊了'; break;
}
statusIndicator.textContent = `状态: ${statusText} (第${side}面)`;
}
function flipPotato() {
if (!gameActive) return;
if (bossActive) {
bossAlert += 30;
showMessage("老板发现你在煎薯饼!警觉度大幅上升!", 2000);
}
if (potatoState === 'perfect') {
if (side === 1) {
showMessage("完美翻面!继续煎另一面", 1500);
} else {
cookedCount++;
perfectCount++;
showMessage("完美薯饼完成!两面都煎得恰到好处!", 2000);
finishCooking();
return;
}
} else if (potatoState === 'cooking') {
showMessage("翻面有点早,再煎一会儿会更金黄", 1500);
} else if (potatoState === 'burnt') {
cookedCount++;
showMessage("哎呀,煎糊了!只能算普通薯饼", 2000);
finishCooking();
return;
}
side = 2;
cookingTime = 0;
updatePotatoState();
}
function finishCooking() {
clearInterval(cookingInterval);
gameActive = false;
if (bossActive) {
bossAlert += 20;
}
updateUI();
setTimeout(() => {
potatoState = 'raw';
side = 1;
cookingTime = 0;
updatePotatoAppearance();
startBtn.disabled = false;
flipBtn.disabled = true;
if (bossAlert >= 100) {
gameOver();
}
}, 2000);
}
function startBossCheck() {
bossActive = true;
bossEl.classList.add('active');
const checkTime = Math.floor(Math.random() * 3000) + 2000;
bossTimer = setTimeout(() => {
endBossCheck();
}, checkTime);
if (gameActive) {
bossAlert += 10;
updateUI();
}
}
function endBossCheck() {
bossActive = false;
bossEl.classList.remove('active');
}
function gameOver() {
clearIntervals();
gameActive = false;
showMessage(`游戏结束!老板发现了你的秘密!你煎了${cookedCount}个薯饼,其中${perfectCount}个完美!`, 5000);
startBtn.disabled = true;
flipBtn.disabled = true;
}
function updateUI() {
cookedCountEl.textContent = cookedCount;
perfectCountEl.textContent = perfectCount;
bossAlertEl.textContent = `${bossAlert}%`;
cookingTimeEl.textContent = `煎制时间: ${cookingTime}s`;
if (bossAlert > 70) {
bossAlertEl.style.color = '#f44336';
} else if (bossAlert > 40) {
bossAlertEl.style.color = '#ff9800';
} else {
bossAlertEl.style.color = '#4b6cb7';
}
}
function showMessage(text, duration) {
messageEl.textContent = text;
messageEl.style.display = 'block';
setTimeout(() => {
messageEl.style.display = 'none';
}, duration);
}
function clearIntervals() {
clearInterval(cookingInterval);
clearInterval(bossInterval);
clearTimeout(bossTimer);
}
startBtn.addEventListener('click', startCooking);
flipBtn.addEventListener('click', flipPotato);
resetBtn.addEventListener('click', initGame);
potatoCake.addEventListener('click', () => {
if (gameActive && potatoState === 'perfect') {
flipPotato();
}
});
initGame();
</script>
</body>
</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>
<style>
:root {
--primary-color: #2c3e50;
--secondary-color: #34495e;
--accent-color: #e74c3c;
--light-color: #ecf0f1;
--gold-color: #f1c40f;
--dark-color: #1a1a2e;
}
* {
margin: 0;
padding: 0;
box-sizing: border-box;
font-family: 'Georgia', 'Times New Roman', serif;
}
body {
background-color: var(--dark-color);
color: var(--light-color);
min-height: 100vh;
display: flex;
justify-content: center;
align-items: center;
padding: 20px;
background-image: radial-gradient(circle at 10% 20%, rgba(28, 28, 48, 0.9) 0%, rgba(26, 26, 46, 1) 90%);
}
.game-container {
width: 100%;
max-width: 1200px;
background-color: rgba(44, 62, 80, 0.9);
border-radius: 15px;
box-shadow: 0 15px 35px rgba(0, 0, 0, 0.5);
overflow: hidden;
border: 1px solid rgba(255, 255, 255, 0.1);
}
.game-header {
background: linear-gradient(135deg, var(--primary-color) 0%, var(--secondary-color) 100%);
padding: 20px 30px;
text-align: center;
border-bottom: 3px solid var(--accent-color);
position: relative;
overflow: hidden;
}
.game-header h1 {
font-size: 2.8rem;
color: var(--gold-color);
text-shadow: 2px 2px 4px rgba(0, 0, 0, 0.5);
letter-spacing: 2px;
margin-bottom: 10px;
}
.game-header p {
font-size: 1.1rem;
opacity: 0.9;
max-width: 800px;
margin: 0 auto;
line-height: 1.6;
}
.game-content {
display: flex;
min-height: 700px;
}
.game-scene {
flex: 3;
padding: 25px;
background-color: rgba(26, 26, 46, 0.8);
border-right: 2px solid rgba(255, 255, 255, 0.1);
position: relative;
overflow: hidden;
}
.room {
width: 100%;
height: 100%;
background-image: url('data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iMTAwJSIgaGVpZ2h0PSIxMDAlIiB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciPjxkZWZzPjxwYXR0ZXJuIGlkPSJwYXR0ZXJuIiBwYXR0ZXJuVW5pdHM9InVzZXJTcGFjZU9uVXNlIiB3aWR0aD0iNDAiIGhlaWdodD0iNDAiIHBhdHRlcm5UcmFuc2Zvcm09InJvdGF0ZSg0NSkiPjxyZWN0IHg9IjAiIHk9IjAiIHdpZHRoPSIyMCIgaGVpZ2h0PSIyMCIgZmlsbD0icmdiYSg1MiwgNzMsIDk0LCAwLjA1KSIvPjwvcGF0dGVybj48L2RlZnM+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0idXJsKCNwYXR0ZXJuKSIvPjwvc3ZnPg==');
border-radius: 10px;
position: relative;
border: 1px solid rgba(255, 255, 255, 0.1);
}
.room-object {
position: absolute;
cursor: pointer;
transition: all 0.3s ease;
border-radius: 5px;
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
text-align: center;
padding: 10px;
}
.room-object:hover {
transform: scale(1.05);
background-color: rgba(241, 196, 15, 0.1);
box-shadow: 0 0 15px rgba(241, 196, 15, 0.3);
}
.room-object.examined {
opacity: 0.6;
filter: grayscale(0.5);
}
.room-object.found {
background-color: rgba(46, 204, 113, 0.2);
box-shadow: 0 0 10px rgba(46, 204, 113, 0.3);
}
.room-object-icon {
font-size: 2.5rem;
margin-bottom: 8px;
text-shadow: 1px 1px 3px rgba(0, 0, 0, 0.7);
}
.room-object-label {
font-size: 0.9rem;
background-color: rgba(0, 0, 0, 0.7);
padding: 3px 8px;
border-radius: 3px;
white-space: nowrap;
}
#bookshelf {
top: 15%;
left: 10%;
width: 180px;
}
#desk {
top: 60%;
left: 15%;
width: 150px;
}
#painting {
top: 10%;
right: 15%;
width: 140px;
}
#safe {
top: 65%;
right: 20%;
width: 120px;
}
#clock {
top: 40%;
left: 50%;
transform: translateX(-50%);
width: 100px;
}
#door {
bottom: 10%;
left: 50%;
transform: translateX(-50%);
width: 120px;
}
.game-ui {
flex: 1;
padding: 25px;
display: flex;
flex-direction: column;
gap: 25px;
}
.game-stats {
background-color: rgba(26, 26, 46, 0.8);
border-radius: 10px;
padding: 20px;
border: 1px solid rgba(255, 255, 255, 0.1);
}
.stat-item {
display: flex;
justify-content: space-between;
align-items: center;
margin-bottom: 15px;
padding-bottom: 15px;
border-bottom: 1px solid rgba(255, 255, 255, 0.1);
}
.stat-item:last-child {
margin-bottom: 0;
padding-bottom: 0;
border-bottom: none;
}
.stat-label {
font-size: 1rem;
color: #aaa;
}
.stat-value {
font-size: 1.4rem;
font-weight: bold;
color: var(--light-color);
}
#timer {
color: var(--accent-color);
font-family: 'Courier New', monospace;
font-size: 1.6rem;
letter-spacing: 2px;
}
.inventory {
background-color: rgba(26, 26, 46, 0.8);
border-radius: 10px;
padding: 20px;
border: 1px solid rgba(255, 255, 255, 0.1);
flex-grow: 1;
}
.inventory h3 {
color: var(--gold-color);
margin-bottom: 15px;
font-size: 1.3rem;
border-bottom: 1px solid rgba(255, 255, 255, 0.1);
padding-bottom: 10px;
}
.inventory-items {
display: flex;
flex-wrap: wrap;
gap: 15px;
min-height: 150px;
}
.inventory-item {
width: 70px;
height: 70px;
background-color: rgba(52, 73, 94, 0.7);
border-radius: 8px;
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
cursor: pointer;
transition: all 0.2s;
border: 2px solid transparent;
position: relative;
}
.inventory-item:hover {
transform: translateY(-5px);
border-color: var(--gold-color);
box-shadow: 0 5px 15px rgba(0, 0, 0, 0.3);
}
.inventory-item-icon {
font-size: 1.8rem;
margin-bottom: 5px;
}
.inventory-item-name {
font-size: 0.7rem;
text-align: center;
padding: 0 5px;
}
.game-log {
background-color: rgba(26, 26, 46, 0.8);
border-radius: 10px;
padding: 20px;
border: 1px solid rgba(255, 255, 255, 0.1);
height: 200px;
overflow-y: auto;
}
.game-log h3 {
color: var(--gold-color);
margin-bottom: 15px;
font-size: 1.3rem;
border-bottom: 1px solid rgba(255, 255, 255, 0.1);
padding-bottom: 10px;
}
.log-entry {
padding: 8px 12px;
margin-bottom: 8px;
background-color: rgba(44, 62, 80, 0.5);
border-radius: 5px;
border-left: 3px solid var(--accent-color);
font-size: 0.9rem;
line-height: 1.4;
}
.log-entry.success {
border-left-color: #2ecc71;
}
.log-entry.clue {
border-left-color: var(--gold-color);
}
.controls {
display: flex;
gap: 15px;
margin-top: 20px;
}
button {
padding: 12px 25px;
font-size: 1rem;
border: none;
border-radius: 8px;
cursor: pointer;
font-weight: bold;
transition: all 0.3s;
flex: 1;
}
#restart-btn {
background-color: var(--secondary-color);
color: var(--light-color);
}
#restart-btn:hover {
background-color: #3d566e;
}
#hint-btn {
background-color: var(--accent-color);
color: white;
}
#hint-btn:hover {
background-color: #c0392b;
}
.modal {
display: none;
position: fixed;
top: 0;
left: 0;
width: 100%;
height: 100%;
background-color: rgba(0, 0, 0, 0.85);
z-index: 1000;
justify-content: center;
align-items: center;
}
.modal-content {
background-color: var(--primary-color);
width: 90%;
max-width: 600px;
border-radius: 15px;
overflow: hidden;
border: 2px solid var(--gold-color);
box-shadow: 0 0 50px rgba(241, 196, 15, 0.3);
}
.modal-header {
background-color: var(--secondary-color);
padding: 20px;
border-bottom: 1px solid rgba(255, 255, 255, 0.1);
display: flex;
justify-content: space-between;
align-items: center;
}
.modal-header h2 {
color: var(--gold-color);
font-size: 1.8rem;
}
.close-modal {
background: none;
border: none;
color: var(--light-color);
font-size: 1.8rem;
cursor: pointer;
padding: 0;
width: 30px;
height: 30px;
display: flex;
align-items: center;
justify-content: center;
}
.modal-body {
padding: 25px;
max-height: 500px;
overflow-y: auto;
}
.puzzle {
margin-bottom: 20px;
}
.puzzle h3 {
color: var(--gold-color);
margin-bottom: 15px;
font-size: 1.3rem;
}
.puzzle-input {
width: 100%;
padding: 12px;
background-color: rgba(26, 26, 46, 0.8);
border: 1px solid rgba(255, 255, 255, 0.2);
border-radius: 5px;
color: white;
font-size: 1.1rem;
margin-bottom: 15px;
}
.puzzle-button {
background-color: var(--accent-color);
color: white;
border: none;
padding: 12px 25px;
border-radius: 5px;
cursor: pointer;
font-weight: bold;
transition: background-color 0.3s;
}
.puzzle-button:hover {
background-color: #c0392b;
}
.clue-text {
background-color: rgba(26, 26, 46, 0.8);
padding: 15px;
border-radius: 8px;
border-left: 4px solid var(--gold-color);
margin-bottom: 15px;
line-height: 1.6;
}
.success-screen {
text-align: center;
padding: 40px;
}
.success-screen h2 {
color: #2ecc71;
font-size: 2.5rem;
margin-bottom: 20px;
}
.success-screen p {
font-size: 1.2rem;
margin-bottom: 30px;
line-height: 1.6;
}
@media (max-width: 992px) {
.game-content {
flex-direction: column;
}
.game-scene {
height: 500px;
border-right: none;
border-bottom: 2px solid rgba(255, 255, 255, 0.1);
}
}
@media (max-width: 768px) {
.room-object {
transform: scale(0.8);
}
.room-object:hover {
transform: scale(0.85);
}
.game-header h1 {
font-size: 2rem;
}
.controls {
flex-direction: column;
}
}
.pulse {
animation: pulse 2s infinite;
}
@keyframes pulse {
0% { box-shadow: 0 0 0 0 rgba(241, 196, 15, 0.4); }
70% { box-shadow: 0 0 0 15px rgba(241, 196, 15, 0); }
100% { box-shadow: 0 0 0 0 rgba(241, 196, 15, 0); }
}
</style>
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.4.0/css/all.min.css">
</head>
<body>
<div class="game-container">
<div class="game-header">
<h1>密室逃脱:时间之钥</h1>
<p>你被困在一个神秘的书房中。寻找线索、解开谜题,在时间耗尽前逃离!</p>
</div>
<div class="game-content">
<div class="game-scene">
<div class="room" id="room">
<!-- 房间中的可交互物体 -->
<div class="room-object" id="bookshelf" data-object="bookshelf">
<div class="room-object-icon">📚</div>
<div class="room-object-label">书架</div>
</div>
<div class="room-object" id="desk" data-object="desk">
<div class="room-object-icon">💼</div>
<div class="room-object-label">书桌</div>
</div>
<div class="room-object" id="painting" data-object="painting">
<div class="room-object-icon">🖼️</div>
<div class="room-object-label">油画</div>
</div>
<div class="room-object" id="safe" data-object="safe">
<div class="room-object-icon">🔒</div>
<div class="room-object-label">保险箱</div>
</div>
<div class="room-object" id="clock" data-object="clock">
<div class="room-object-icon">🕰️</div>
<div class="room-object-label">挂钟</div>
</div>
<div class="room-object" id="door" data-object="door">
<div class="room-object-icon">🚪</div>
<div class="room-object-label">大门</div>
</div>
</div>
</div>
<div class="game-ui">
<div class="game-stats">
<div class="stat-item">
<div class="stat-label">剩余时间</div>
<div id="timer" class="stat-value">45:00</div>
</div>
<div class="stat-item">
<div class="stat-label">找到线索</div>
<div id="clues-found" class="stat-value">0/6</div>
</div>
<div class="stat-item">
<div class="stat-label">收集物品</div>
<div id="items-found" class="stat-value">0/5</div>
</div>
<div class="stat-item">
<div class="stat-label">谜题进度</div>
<div id="puzzles-solved" class="stat-value">0/3</div>
</div>
</div>
<div class="inventory">
<h3>物品栏</h3>
<div class="inventory-items" id="inventory">
<!-- 物品将通过JavaScript动态添加 -->
<div class="inventory-empty">暂无物品</div>
</div>
</div>
<div class="game-log">
<h3>游戏日志</h3>
<div id="log-container">
<div class="log-entry">你醒来发现自己被困在一个陌生的书房中。门被锁住了,你需要找到逃出去的方法。</div>
<div class="log-entry">房间里似乎有一些线索,仔细检查每个物体。</div>
</div>
</div>
<div class="controls">
<button id="restart-btn">重新开始</button>
<button id="hint-btn">获取提示</button>
</div>
</div>
</div>
</div>
<!-- 书架谜题模态框 -->
<div class="modal" id="bookshelf-modal">
<div class="modal-content">
<div class="modal-header">
<h2>书架谜题</h2>
<button class="close-modal" data-modal="bookshelf-modal">×</button>
</div>
<div class="modal-body">
<div class="clue-text">
<p>书架上有一排奇怪的书籍,书名似乎隐藏着密码。</p>
<p>书籍顺序:<strong>时间、钥匙、谜题、逃脱、密室</strong></p>
<p>提示:每本书名的第一个字拼音的首字母</p>
</div>
<div class="puzzle">
<h3>输入密码(5位字母)</h3>
<input type="text" id="bookshelf-code" class="puzzle-input" maxlength="5" placeholder="输入5位字母密码">
<button class="puzzle-button" id="bookshelf-submit">提交</button>
</div>
</div>
</div>
</div>
<!-- 油画谜题模态框 -->
<div class="modal" id="painting-modal">
<div class="modal-content">
<div class="modal-header">
<h2>油画谜题</h2>
<button class="close-modal" data-modal="painting-modal">×</button>
</div>
<div class="modal-body">
<div class="clue-text">
<p>油画描绘了一个日落的场景,但有些地方不对劲。</p>
<p>画中的时钟显示:<strong>6:30</strong></p>
<p>但太阳的位置显示应该是<strong>下午</strong>而非清晨</p>
<p>提示:将时间转换为24小时制</p>
</div>
<div class="puzzle">
<h3>输入时间代码(4位数字)</h3>
<input type="text" id="painting-code" class="puzzle-input" maxlength="4" placeholder="输入4位数字密码">
<button class="puzzle-button" id="painting-submit">提交</button>
</div>
</div>
</div>
</div>
<!-- 保险箱谜题模态框 -->
<div class="modal" id="safe-modal">
<div class="modal-content">
<div class="modal-header">
<h2>保险箱谜题</h2>
<button class="close-modal" data-modal="safe-modal">×</button>
</div>
<div class="modal-body">
<div class="clue-text">
<p>保险箱需要3位数字密码。</p>
<p>你在书桌上找到一张纸条:</p>
<p><em>"书房里有三件重要的物品:</em></p>
<p><em>书架上的书(5本)</em></p>
<p><em>油画中的时间(1830)</em></p>
<p><em>挂钟的指针(指向4和8)"</em></p>
<p>提示:将这些数字按顺序组合</p>
</div>
<div class="puzzle">
<h3>输入保险箱密码(3位数字)</h3>
<input type="text" id="safe-code" class="puzzle-input" maxlength="3" placeholder="输入3位数字密码">
<button class="puzzle-button" id="safe-submit">提交</button>
</div>
</div>
</div>
</div>
<!-- 大门谜题模态框 -->
<div class="modal" id="door-modal">
<div class="modal-content">
<div class="modal-header">
<h2>大门谜题</h2>
<button class="close-modal" data-modal="door-modal">×</button>
</div>
<div class="modal-body">
<div class="clue-text">
<p>大门需要最终密码才能打开。</p>
<p>结合你找到的所有线索:</p>
<p>1. 书架密码:SJMTS (时间、钥匙、谜题、逃脱、密室的拼音首字母)</p>
<p>2. 油画密码:1830 (6:30 PM的24小时制)</p>
<p>3. 保险箱密码:548 (5本书,时间1830中的18,时钟4和8)</p>
<p>最终密码是这些数字的某种组合...</p>
</div>
<div class="puzzle">
<h3>输入最终密码(6位数字)</h3>
<input type="text" id="door-code" class="puzzle-input" maxlength="6" placeholder="输入6位数字密码">
<button class="puzzle-button" id="door-submit">提交</button>
</div>
</div>
</div>
</div>
<!-- 游戏成功模态框 -->
<div class="modal" id="success-modal">
<div class="modal-content">
<div class="success-screen">
<h2><i class="fas fa-trophy"></i> 逃脱成功!</h2>
<p id="success-message">你成功逃出了密室!</p>
<p>所用时间: <span id="final-time">45:00</span></p>
<p>找到线索: <span id="final-clues">0/6</span></p>
<p>收集物品: <span id="final-items">0/5</span></p>
<p>解谜数量: <span id="final-puzzles">0/3</span></p>
<button id="play-again-btn" class="puzzle-button" style="margin-top: 30px; padding: 15px 40px;">再玩一次</button>
</div>
</div>
</div>
<!-- 游戏失败模态框 -->
<div class="modal" id="fail-modal">
<div class="modal-content">
<div class="success-screen">
<h2 style="color: var(--accent-color);"><i class="fas fa-hourglass-end"></i> 时间耗尽!</h2>
<p>很遗憾,你没能在规定时间内逃出密室。</p>
<p>你找到了 <span id="fail-clues">0</span> 条线索,解开了 <span id="fail-puzzles">0</span> 个谜题。</p>
<button id="retry-btn" class="puzzle-button" style="margin-top: 30px; padding: 15px 40px;">重新挑战</button>
</div>
</div>
</div>
<!-- 提示模态框 -->
<div class="modal" id="hint-modal">
<div class="modal-content">
<div class="modal-header">
<h2>游戏提示</h2>
<button class="close-modal" data-modal="hint-modal">×</button>
</div>
<div class="modal-body">
<div class="clue-text">
<h3>游戏提示:</h3>
<p>1. 仔细检查房间中的每个物体,它们都隐藏着线索。</p>
<p>2. 书架谜题答案:<strong>SJMTS</strong> (时间、钥匙、谜题、逃脱、密室的拼音首字母)</p>
<p>3. 油画谜题答案:<strong>1830</strong> (下午6:30的24小时制表示)</p>
<p>4. 保险箱密码:<strong>548</strong> (5本书,18来自油画,4和8来自时钟)</p>
<p>5. 大门最终密码:<strong>518430</strong> (组合所有数字:5本书,18:30时间,4和8时钟)</p>
<p>6. 按顺序解谜:书架→油画→时钟→书桌→保险箱→大门</p>
</div>
</div>
</div>
</div>
<script>
let gameState = {
timeLeft: 45 * 60,
cluesFound: 0,
totalClues: 6,
itemsFound: 0,
totalItems: 5,
puzzlesSolved: 0,
totalPuzzles: 3,
inventory: [],
examinedObjects: [],
solvedPuzzles: {
bookshelf: false,
painting: false,
safe: false,
door: false
},
foundItems: {
key: false,
note: false,
magnifier: false,
candle: false,
clockHand: false
},
gameActive: true,
timerInterval: null
};
const timerEl = document.getElementById('timer');
const cluesFoundEl = document.getElementById('clues-found');
const itemsFoundEl = document.getElementById('items-found');
const puzzlesSolvedEl = document.getElementById('puzzles-solved');
const inventoryEl = document.getElementById('inventory');
const logContainer = document.getElementById('log-container');
function initGame() {
gameState = {
timeLeft: 45 * 60,
cluesFound: 0,
totalClues: 6,
itemsFound: 0,
totalItems: 5,
puzzlesSolved: 0,
totalPuzzles: 3,
inventory: [],
examinedObjects: [],
solvedPuzzles: {
bookshelf: false,
painting: false,
safe: false,
door: false
},
foundItems: {
key: false,
note: false,
magnifier: false,
candle: false,
clockHand: false
},
gameActive: true
};
updateUI();
logContainer.innerHTML = '';
addLogEntry("你醒来发现自己被困在一个陌生的书房中。门被锁住了,你需要找到逃出去的方法。");
addLogEntry("房间里似乎有一些线索,仔细检查每个物体。", "clue");
inventoryEl.innerHTML = '<div class="inventory-empty">暂无物品</div>';
document.querySelectorAll('.room-object').forEach(obj => {
obj.classList.remove('examined', 'found');
});
if (gameState.timerInterval) clearInterval(gameState.timerInterval);
gameState.timerInterval = setInterval(updateTimer, 1000);
document.querySelectorAll('.modal').forEach(modal => {
modal.style.display = 'none';
});
}
function updateTimer() {
if (!gameState.gameActive) return;
gameState.timeLeft--;
const minutes = Math.floor(gameState.timeLeft / 60);
const seconds = gameState.timeLeft % 60;
timerEl.textContent = `${minutes.toString().padStart(2, '0')}:${seconds.toString().padStart(2, '0')}`;
if (gameState.timeLeft <= 5 * 60) {
timerEl.style.color = '#e74c3c';
if (gameState.timeLeft === 5 * 60) {
addLogEntry("警告:只剩下5分钟了!加快速度!", "clue");
}
}
if (gameState.timeLeft <= 0) {
clearInterval(gameState.timerInterval);
gameState.gameActive = false;
showFailModal();
}
}
function updateUI() {
cluesFoundEl.textContent = `${gameState.cluesFound}/${gameState.totalClues}`;
itemsFoundEl.textContent = `${gameState.itemsFound}/${gameState.totalItems}`;
puzzlesSolvedEl.textContent = `${gameState.puzzlesSolved}/${gameState.totalPuzzles}`;
updateInventory();
}
function updateInventory() {
if (gameState.inventory.length === 0) {
inventoryEl.innerHTML = '<div class="inventory-empty">暂无物品</div>';
return;
}
inventoryEl.innerHTML = '';
gameState.inventory.forEach(item => {
const itemEl = document.createElement('div');
itemEl.className = 'inventory-item';
itemEl.innerHTML = `
<div class="inventory-item-icon">${item.icon}</div>
<div class="inventory-item-name">${item.name}</div>
`;
itemEl.title = item.description;
inventoryEl.appendChild(itemEl);
});
}
function addLogEntry(text, type = "normal") {
const logEntry = document.createElement('div');
logEntry.className = `log-entry ${type === 'success' ? 'success' : ''} ${type === 'clue' ? 'clue' : ''}`;
logEntry.textContent = text;
logContainer.appendChild(logEntry);
logContainer.scrollTop = logContainer.scrollHeight;
}
function examineObject(objectId) {
const objectEl = document.getElementById(objectId);
if (gameState.examinedObjects.includes(objectId)) {
addLogEntry(`你已经检查过${getObjectName(objectId)}了。`);
return;
}
gameState.examinedObjects.push(objectId);
objectEl.classList.add('examined');
switch(objectId) {
case 'bookshelf':
addLogEntry("你检查了书架,发现一些书籍排列得很奇怪。其中五本书的书名似乎隐藏着密码。", "clue");
gameState.cluesFound++;
setTimeout(() => {
document.getElementById('bookshelf-modal').style.display = 'flex';
}, 500);
break;
case 'desk':
addLogEntry("你在书桌抽屉里找到一把旧钥匙和一张写有提示的纸条。", "success");
if (!gameState.foundItems.key) {
gameState.inventory.push({
id: 'key',
name: '旧钥匙',
icon: '🗝️',
description: '一把生锈的旧钥匙,可能能打开什么东西。'
});
gameState.foundItems.key = true;
gameState.itemsFound++;
}
if (!gameState.foundItems.note) {
gameState.inventory.push({
id: 'note',
name: '提示纸条',
icon: '📜',
description: '一张写着提示的纸条:"书房里有三件重要的物品..."'
});
gameState.foundItems.note = true;
gameState.cluesFound++;
}
break;
case 'painting':
addLogEntry("你仔细观察油画,发现画中的时钟显示的时间与太阳位置不符。", "clue");
gameState.cluesFound++;
setTimeout(() => {
document.getElementById('painting-modal').style.display = 'flex';
}, 500);
break;
case 'safe':
if (gameState.solvedPuzzles.bookshelf && gameState.solvedPuzzles.painting) {
addLogEntry("保险箱需要密码才能打开。", "clue");
setTimeout(() => {
document.getElementById('safe-modal').style.display = 'flex';
}, 500);
} else {
addLogEntry("保险箱被锁住了,需要找到密码才能打开。");
}
break;
case 'clock':
addLogEntry("挂钟的指针停在4和8的位置,但钟已经不走了。", "clue");
if (!gameState.foundItems.clockHand) {
const hasMagnifier = gameState.inventory.some(item => item.id === 'magnifier');
if (hasMagnifier) {
addLogEntry("你用放大镜仔细检查,发现钟的背后有一个隐藏的隔间,里面有一根小蜡烛。", "success");
gameState.inventory.push({
id: 'candle',
name: '小蜡烛',
icon: '🕯️',
description: '一根小蜡烛,也许能提供照明。'
});
gameState.foundItems.candle = true;
gameState.itemsFound++;
} else {
addLogEntry("挂钟的指针很奇怪,但你看不清细节。也许需要一个放大镜?");
}
gameState.cluesFound++;
}
break;
case 'door':
if (gameState.solvedPuzzles.safe) {
addLogEntry("大门需要最终密码才能打开。你找到了保险箱里的密码提示。", "clue");
setTimeout(() => {
document.getElementById('door-modal').style.display = 'flex';
}, 500);
} else {
addLogEntry("大门被牢牢锁住,需要密码才能打开。");
}
break;
}
updateUI();
objectEl.classList.add('pulse');
setTimeout(() => {
objectEl.classList.remove('pulse');
}, 2000);
}
function getObjectName(objectId) {
const names = {
'bookshelf': '书架',
'desk': '书桌',
'painting': '油画',
'safe': '保险箱',
'clock': '挂钟',
'door': '大门'
};
return names[objectId] || '物体';
}
function solveBookshelfPuzzle() {
const code = document.getElementById('bookshelf-code').value.toUpperCase();
if (code === 'SJMTS') {
gameState.solvedPuzzles.bookshelf = true;
gameState.puzzlesSolved++;
addLogEntry("书架谜题已解决!你找到了一个隐藏的放大镜。", "success");
gameState.inventory.push({
id: 'magnifier',
name: '放大镜',
icon: '🔍',
description: '一个精致的放大镜,可以帮助你看清细小的东西。'
});
gameState.foundItems.magnifier = true;
gameState.itemsFound++;
document.getElementById('bookshelf-modal').style.display = 'none';
document.getElementById('bookshelf').classList.add('found');
updateUI();
} else {
addLogEntry("密码错误,再仔细想想。", "clue");
}
}
function solvePaintingPuzzle() {
const code = document.getElementById('painting-code').value;
if (code === '1830') {
gameState.solvedPuzzles.painting = true;
gameState.puzzlesSolved++;
addLogEntry("油画谜题已解决!你发现了时间线索。", "success");
document.getElementById('painting-modal').style.display = 'none';
document.getElementById('painting').classList.add('found');
updateUI();
} else {
addLogEntry("时间不对,再仔细检查油画。", "clue");
}
}
function solveSafePuzzle() {
const code = document.getElementById('safe-code').value;
if (code === '548') {
gameState.solvedPuzzles.safe = true;
gameState.puzzlesSolved++;
addLogEntry("保险箱已打开!你找到了大门的密码提示。", "success");
document.getElementById('safe-modal').style.display = 'none';
document.getElementById('safe').classList.add('found');
updateUI();
} else {
addLogEntry("密码错误,检查你找到的所有线索。", "clue");
}
}
function solveDoorPuzzle() {
const code = document.getElementById('door-code').value;
if (code === '518430') {
gameState.solvedPuzzles.door = true;
gameState.gameActive = false;
clearInterval(gameState.timerInterval);
const minutes = Math.floor((45 * 60 - gameState.timeLeft) / 60);
const seconds = (45 * 60 - gameState.timeLeft) % 60;
const timeUsed = `${minutes.toString().padStart(2, '0')}:${seconds.toString().padStart(2, '0')}`;
document.getElementById('final-time').textContent = timeUsed;
document.getElementById('final-clues').textContent = `${gameState.cluesFound}/${gameState.totalClues}`;
document.getElementById('final-items').textContent = `${gameState.itemsFound}/${gameState.totalItems}`;
document.getElementById('final-puzzles').textContent = `${gameState.puzzlesSolved}/${gameState.totalPuzzles}`;
let message = "恭喜!你成功逃出了密室!";
if (gameState.timeLeft > 30 * 60) {
message += " 你的速度非常快,堪称逃脱大师!";
} else if (gameState.timeLeft > 15 * 60) {
message += " 做得不错,在时间耗尽前成功逃脱!";
} else {
message += " 真是惊险刺激,差点就没时间了!";
}
document.getElementById('success-message').textContent = message;
document.getElementById('door-modal').style.display = 'none';
document.getElementById('success-modal').style.display = 'flex';
addLogEntry("你输入了正确的密码!大门缓缓打开...你成功逃出了密室!", "success");
} else {
addLogEntry("密码错误,再仔细组合所有线索。", "clue");
}
}
function showFailModal() {
document.getElementById('fail-clues').textContent = gameState.cluesFound;
document.getElementById('fail-puzzles').textContent = gameState.puzzlesSolved;
document.getElementById('fail-modal').style.display = 'flex';
}
function showHintModal() {
document.getElementById('hint-modal').style.display = 'flex';
}
function setupEventListeners() {
document.querySelectorAll('.room-object').forEach(obj => {
obj.addEventListener('click', function() {
if (!gameState.gameActive) return;
const objectId = this.id;
examineObject(objectId);
});
});
document.querySelectorAll('.close-modal').forEach(btn => {
btn.addEventListener('click', function() {
const modalId = this.getAttribute('data-modal');
document.getElementById(modalId).style.display = 'none';
});
});
document.getElementById('bookshelf-submit').addEventListener('click', solveBookshelfPuzzle);
document.getElementById('painting-submit').addEventListener('click', solvePaintingPuzzle);
document.getElementById('safe-submit').addEventListener('click', solveSafePuzzle);
document.getElementById('door-submit').addEventListener('click', solveDoorPuzzle);
document.getElementById('bookshelf-code').addEventListener('keypress', function(e) {
if (e.key === 'Enter') solveBookshelfPuzzle();
});
document.getElementById('painting-code').addEventListener('keypress', function(e) {
if (e.key === 'Enter') solvePaintingPuzzle();
});
document.getElementById('safe-code').addEventListener('keypress', function(e) {
if (e.key === 'Enter') solveSafePuzzle();
});
document.getElementById('door-code').addEventListener('keypress', function(e) {
if (e.key === 'Enter') solveDoorPuzzle();
});
document.getElementById('restart-btn').addEventListener('click', initGame);
document.getElementById('hint-btn').addEventListener('click', showHintModal);
document.getElementById('play-again-btn').addEventListener('click', initGame);
document.getElementById('retry-btn').addEventListener('click', initGame);
document.querySelectorAll('.modal').forEach(modal => {
modal.addEventListener('click', function(e) {
if (e.target === this) {
this.style.display = 'none';
}
});
});
}
window.onload = function() {
initGame();
setupEventListeners();
setTimeout(() => {
addLogEntry("提示:点击房间中的物体进行检查和互动。", "clue");
}, 3000);
};
</script>
</body>
</html>