Files
aiData/static/Test/地狱大转盘V5.html
HuangHai 1f6a48004b 'commit'
2026-01-25 18:17:37 +08:00

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>