436 lines
14 KiB
HTML
436 lines
14 KiB
HTML
<!DOCTYPE html>
|
|
<html lang="zh-CN">
|
|
<head>
|
|
<meta charset="UTF-8">
|
|
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
|
<title>🔥 地狱炙烤 V8 - 谁是最后那块肉? 🔥</title>
|
|
<style>
|
|
@import url('https://fonts.googleapis.com/css2?family=ZCOOL+KuaiLe&display=swap');
|
|
|
|
:root {
|
|
--fire-orange: #ff9f43;
|
|
--fire-red: #ee5253;
|
|
--charcoal: #2d3436;
|
|
--danger-bg: #1a1a1a;
|
|
}
|
|
|
|
body {
|
|
margin: 0;
|
|
padding: 0;
|
|
background-color: var(--danger-bg);
|
|
color: #fff;
|
|
font-family: 'ZCOOL KuaiLe', cursive, sans-serif;
|
|
height: 100vh;
|
|
display: flex;
|
|
flex-direction: column;
|
|
align-items: center;
|
|
justify-content: center;
|
|
overflow: hidden;
|
|
user-select: none;
|
|
}
|
|
|
|
h1 {
|
|
font-size: 3rem;
|
|
color: var(--fire-orange);
|
|
text-shadow: 0 0 20px var(--fire-red);
|
|
margin-bottom: 10px;
|
|
z-index: 100;
|
|
}
|
|
|
|
/* 心理压力:温度计 */
|
|
.temp-gauge {
|
|
width: 600px;
|
|
height: 30px;
|
|
background: #000;
|
|
border: 3px solid #555;
|
|
border-radius: 15px;
|
|
margin-bottom: 20px;
|
|
position: relative;
|
|
overflow: hidden;
|
|
z-index: 100;
|
|
}
|
|
|
|
#tempFill {
|
|
width: 0%;
|
|
height: 100%;
|
|
background: linear-gradient(90deg, #ff9f43, #ee5253, #ff0000);
|
|
transition: width 0.5s linear;
|
|
}
|
|
|
|
.temp-label {
|
|
position: absolute;
|
|
width: 100%;
|
|
text-align: center;
|
|
line-height: 30px;
|
|
font-size: 1.2rem;
|
|
font-weight: bold;
|
|
color: #fff;
|
|
text-shadow: 1px 1px 2px #000;
|
|
}
|
|
|
|
/* 烤炉区域 */
|
|
.grill-area {
|
|
position: relative;
|
|
width: 800px;
|
|
height: 500px;
|
|
background: radial-gradient(circle at center, #3d3d3d 0%, #1a1a1a 100%);
|
|
border: 15px solid #444;
|
|
border-radius: 20px;
|
|
display: flex;
|
|
flex-wrap: wrap;
|
|
align-content: center;
|
|
justify-content: center;
|
|
gap: 20px;
|
|
padding: 20px;
|
|
box-shadow: inset 0 0 100px rgba(255, 69, 0, 0.2);
|
|
}
|
|
|
|
/* 铁丝网效果 */
|
|
.grill-area::before {
|
|
content: '';
|
|
position: absolute;
|
|
top: 0; left: 0; right: 0; bottom: 0;
|
|
background-image:
|
|
linear-gradient(90deg, rgba(255,255,255,0.05) 1px, transparent 1px),
|
|
linear-gradient(rgba(255,255,255,0.05) 1px, transparent 1px);
|
|
background-size: 20px 20px;
|
|
pointer-events: none;
|
|
}
|
|
|
|
/* 学生头像(肉块) */
|
|
.student-meat {
|
|
position: relative;
|
|
width: 120px;
|
|
height: 120px;
|
|
border-radius: 15px;
|
|
border: 4px solid #555;
|
|
background: #fff;
|
|
overflow: hidden;
|
|
transition: all 0.5s cubic-bezier(0.175, 0.885, 0.32, 1.275);
|
|
z-index: 10;
|
|
}
|
|
|
|
.student-meat img {
|
|
width: 100%;
|
|
height: 100%;
|
|
object-fit: cover;
|
|
}
|
|
|
|
/* 危险状态:颤抖 */
|
|
.student-meat.danger {
|
|
animation: shake 0.1s infinite;
|
|
border-color: var(--fire-red);
|
|
box-shadow: 0 0 20px var(--fire-red);
|
|
}
|
|
|
|
@keyframes shake {
|
|
0% { transform: translate(1px, 1px) rotate(0deg); }
|
|
20% { transform: translate(-1px, -2px) rotate(-1deg); }
|
|
40% { transform: translate(-3px, 0px) rotate(1deg); }
|
|
60% { transform: translate(3px, 2px) rotate(0deg); }
|
|
80% { transform: translate(1px, -1px) rotate(1deg); }
|
|
100% { transform: translate(-1px, 2px) rotate(-1deg); }
|
|
}
|
|
|
|
/* 淘汰状态:被烤焦 */
|
|
.student-meat.charred {
|
|
filter: grayscale(1) brightness(0.2) blur(2px);
|
|
transform: scale(0.8);
|
|
opacity: 0.5;
|
|
border-color: #000;
|
|
}
|
|
|
|
/* 幸存状态:飞走 */
|
|
.student-meat.saved {
|
|
transform: translateY(-500px) rotate(360deg) scale(0);
|
|
opacity: 0;
|
|
}
|
|
|
|
/* 火焰特效层 */
|
|
.fire-layer {
|
|
position: absolute;
|
|
bottom: -50px;
|
|
left: 0;
|
|
width: 100%;
|
|
height: 200px;
|
|
background: url('https://www.transparenttextures.com/patterns/carbon-fibre.png'); /* 占位背景 */
|
|
pointer-events: none;
|
|
z-index: 5;
|
|
opacity: 0;
|
|
transition: opacity 2s;
|
|
}
|
|
|
|
/* 最终结果弹窗 */
|
|
#resultOverlay {
|
|
position: fixed;
|
|
top: 0; left: 0; width: 100%; height: 100%;
|
|
background: rgba(0,0,0,0.95);
|
|
display: none;
|
|
flex-direction: column;
|
|
align-items: center;
|
|
justify-content: center;
|
|
z-index: 1000;
|
|
}
|
|
|
|
.roasted-card {
|
|
position: relative;
|
|
background: #000;
|
|
padding: 40px;
|
|
border-radius: 30px;
|
|
border: 10px solid var(--fire-orange);
|
|
text-align: center;
|
|
box-shadow: 0 0 100px var(--fire-red);
|
|
animation: emerge 1s forwards;
|
|
}
|
|
|
|
@keyframes emerge {
|
|
from { transform: scale(0) rotate(-20deg); }
|
|
to { transform: scale(1) rotate(0deg); }
|
|
}
|
|
|
|
.roasted-img {
|
|
width: 300px;
|
|
height: 300px;
|
|
border-radius: 20px;
|
|
border: 5px solid #fff;
|
|
object-fit: cover;
|
|
}
|
|
|
|
.roasted-title {
|
|
font-size: 4rem;
|
|
color: var(--fire-red);
|
|
margin: 20px 0;
|
|
text-shadow: 0 0 10px #fff;
|
|
}
|
|
|
|
/* 控制按钮 */
|
|
#startBtn {
|
|
margin-top: 30px;
|
|
padding: 15px 60px;
|
|
font-size: 2rem;
|
|
background: linear-gradient(to bottom, #ff9f43, #ee5253);
|
|
color: white;
|
|
border: none;
|
|
border-radius: 50px;
|
|
cursor: pointer;
|
|
box-shadow: 0 10px 0 #8b0000;
|
|
transition: all 0.1s;
|
|
z-index: 100;
|
|
}
|
|
|
|
#startBtn:active {
|
|
transform: translateY(5px);
|
|
box-shadow: 0 5px 0 #8b0000;
|
|
}
|
|
|
|
#startBtn:disabled {
|
|
background: #555;
|
|
box-shadow: 0 5px 0 #222;
|
|
cursor: not-allowed;
|
|
}
|
|
|
|
/* 吐槽气泡 */
|
|
.bubble {
|
|
position: absolute;
|
|
background: white;
|
|
color: black;
|
|
padding: 5px 10px;
|
|
border-radius: 10px;
|
|
font-size: 0.9rem;
|
|
top: -40px;
|
|
left: 50%;
|
|
transform: translateX(-50%);
|
|
white-space: nowrap;
|
|
pointer-events: none;
|
|
animation: bounceIn 0.3s forwards;
|
|
}
|
|
|
|
@keyframes bounceIn {
|
|
from { transform: translateX(-50%) scale(0); }
|
|
to { transform: translateX(-50%) scale(1); }
|
|
}
|
|
|
|
</style>
|
|
</head>
|
|
<body>
|
|
|
|
<h1>🔥 地狱炙烤 V8 🔥</h1>
|
|
|
|
<div class="temp-gauge">
|
|
<div id="tempFill"></div>
|
|
<div class="temp-label">当前温度: <span id="tempVal">25</span>°C</div>
|
|
</div>
|
|
|
|
<div class="grill-area" id="grill">
|
|
<!-- 学生肉块将由JS生成 -->
|
|
</div>
|
|
|
|
<button id="startBtn" onclick="startRoasting()">开始加火!</button>
|
|
|
|
<div id="resultOverlay">
|
|
<div class="roasted-card">
|
|
<div style="font-size: 2rem; color: #ff9f43;">恭喜!这块肉烤得恰到好处!</div>
|
|
<img src="" class="roasted-img" id="resultImg">
|
|
<div class="roasted-title" id="resultName">???</div>
|
|
<button id="startBtn" onclick="location.reload()" style="background: #27ae60; box-shadow: 0 10px 0 #1e8449;">再烤一锅</button>
|
|
</div>
|
|
</div>
|
|
|
|
<script>
|
|
const totalStudents = 14;
|
|
const imagePath = './Result/';
|
|
const grill = document.getElementById('grill');
|
|
const students = [];
|
|
const scaryQuotes = ["好烫!好烫!", "救命啊!", "我不想被烤!", "火太大了!", "轮到谁了?", "鸭梨山大...", "感觉要熟了"];
|
|
|
|
// 音效系统
|
|
const audioCtx = new (window.AudioContext || window.webkitAudioContext)();
|
|
function playSound(freq, type, duration, vol = 0.1) {
|
|
const osc = audioCtx.createOscillator();
|
|
const gain = audioCtx.createGain();
|
|
osc.type = type;
|
|
osc.frequency.setValueAtTime(freq, audioCtx.currentTime);
|
|
gain.gain.setValueAtTime(vol, audioCtx.currentTime);
|
|
gain.gain.exponentialRampToValueAtTime(0.01, audioCtx.currentTime + duration);
|
|
osc.connect(gain);
|
|
gain.connect(audioCtx.destination);
|
|
osc.start();
|
|
osc.stop(audioCtx.currentTime + duration);
|
|
}
|
|
|
|
// 心跳/节奏音
|
|
let heartbeatInterval;
|
|
function startHeartbeat(bpm) {
|
|
clearInterval(heartbeatInterval);
|
|
heartbeatInterval = setInterval(() => {
|
|
playSound(150, 'sine', 0.1, 0.2);
|
|
setTimeout(() => playSound(100, 'sine', 0.1, 0.2), 150);
|
|
}, (60 / bpm) * 1000);
|
|
}
|
|
|
|
function init() {
|
|
for (let i = 1; i <= totalStudents; i++) {
|
|
const meat = document.createElement('div');
|
|
meat.className = 'student-meat';
|
|
meat.id = `meat-${i}`;
|
|
|
|
const img = document.createElement('img');
|
|
img.src = `${imagePath}${i}.png`;
|
|
img.onerror = () => img.src = 'https://via.placeholder.com/120?text=Meat';
|
|
|
|
meat.appendChild(img);
|
|
grill.appendChild(meat);
|
|
|
|
students.push({
|
|
el: meat,
|
|
id: i,
|
|
status: 'raw' // raw, charred, saved, roasted
|
|
});
|
|
}
|
|
}
|
|
|
|
let temperature = 25;
|
|
let isRoasting = false;
|
|
|
|
async function startRoasting() {
|
|
if (isRoasting) return;
|
|
isRoasting = true;
|
|
document.getElementById('startBtn').disabled = true;
|
|
if (audioCtx.state === 'suspended') audioCtx.resume();
|
|
|
|
// 1. 心理压力启动:心跳声和温度上升
|
|
let bpm = 60;
|
|
startHeartbeat(bpm);
|
|
|
|
// 温度上升动画
|
|
const tempFill = document.getElementById('tempFill');
|
|
const tempVal = document.getElementById('tempVal');
|
|
|
|
// 陆续排除过程
|
|
const aliveList = [...students];
|
|
|
|
while (aliveList.length > 1) {
|
|
// 提高温度和心跳频率
|
|
temperature += Math.floor(Math.random() * 50) + 20;
|
|
bpm += 20;
|
|
startHeartbeat(bpm);
|
|
|
|
tempFill.style.width = (temperature / 1000 * 100) + '%';
|
|
tempVal.innerText = temperature;
|
|
|
|
// 让所有人颤抖
|
|
aliveList.forEach(s => s.el.classList.add('danger'));
|
|
|
|
// 随机吐槽
|
|
if (Math.random() > 0.5) {
|
|
const randomS = aliveList[Math.floor(Math.random() * aliveList.length)];
|
|
showBubble(randomS.el, scaryQuotes[Math.floor(Math.random() * scaryQuotes.length)]);
|
|
}
|
|
|
|
// 心理压力:随机停顿时间(越来越长)
|
|
const waitTime = 1000 + (14 - aliveList.length) * 300;
|
|
await new Promise(r => setTimeout(r, waitTime));
|
|
|
|
// 排除一个:要么被救走,要么被烤焦(视觉上只是排除)
|
|
const removeIdx = Math.floor(Math.random() * aliveList.length);
|
|
const removed = aliveList.splice(removeIdx, 1)[0];
|
|
|
|
if (Math.random() > 0.5) {
|
|
removed.el.classList.remove('danger');
|
|
removed.el.classList.add('saved');
|
|
playSound(440, 'sine', 0.5, 0.1); // 逃生成功音
|
|
} else {
|
|
removed.el.classList.remove('danger');
|
|
removed.el.classList.add('charred');
|
|
playSound(200, 'sawtooth', 0.5, 0.1); // 被淘汰音
|
|
}
|
|
}
|
|
|
|
// 2. 最终时刻:只剩一人
|
|
const winner = aliveList[0];
|
|
temperature = 999;
|
|
tempFill.style.width = '100%';
|
|
tempVal.innerText = temperature;
|
|
|
|
// 最后的挣扎
|
|
winner.el.style.transform = 'scale(1.5)';
|
|
showBubble(winner.el, "不!!!!!!");
|
|
startHeartbeat(240); // 极速心跳
|
|
|
|
await new Promise(r => setTimeout(r, 2000));
|
|
|
|
// 终极火焰
|
|
clearInterval(heartbeatInterval);
|
|
playSound(100, 'noise', 2, 0.3); // 喷火声
|
|
|
|
showResult(winner.id);
|
|
}
|
|
|
|
function showBubble(parent, text) {
|
|
const b = document.createElement('div');
|
|
b.className = 'bubble';
|
|
b.innerText = text;
|
|
parent.appendChild(b);
|
|
setTimeout(() => b.remove(), 1000);
|
|
}
|
|
|
|
function showResult(id) {
|
|
const overlay = document.getElementById('resultOverlay');
|
|
const img = document.getElementById('resultImg');
|
|
const name = document.getElementById('resultName');
|
|
|
|
img.src = `${imagePath}${id}.png`;
|
|
name.innerText = `玩家 ${id} 熟透了!`;
|
|
overlay.style.display = 'flex';
|
|
|
|
// 最终音效
|
|
playSound(523, 'sawtooth', 0.5);
|
|
setTimeout(() => playSound(392, 'sawtooth', 0.5), 200);
|
|
setTimeout(() => playSound(523, 'sawtooth', 1.0), 400);
|
|
}
|
|
|
|
window.onload = init;
|
|
</script>
|
|
</body>
|
|
</html>
|