<!DOCTYPE html>
<html lang=”zh”>
<head>
<meta charset=”UTF-8″>
<meta name=”viewport” content=”width=device-width, initial-scale=1.0″>
<title>击鼓传花游戏</title>
<style>
:root {
–primary-color: #ff6b6b;
–secondary-color: #4ecdc4;
–accent-color: #ffe66d;
–dark-color: #292f36;
–light-color: #f7fff7;
}

body {
font-family: ‘Arial Rounded MT Bold’, ‘Microsoft YaHei’, sans-serif;
text-align: center;
padding: 0;
margin: 0;
background: linear-gradient(135deg, var(–dark-color), #3a4750);
color: var(–light-color);
min-height: 100vh;
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
overflow-x: hidden;
}

.container {
background: rgba(41, 47, 54, 0.8);
border-radius: 20px;
padding: 30px;
box-shadow: 0 10px 30px rgba(0, 0, 0, 0.3);
width: 90%;
max-width: 600px;
backdrop-filter: blur(10px);
border: 1px solid rgba(255, 255, 255, 0.1);
position: relative;
overflow: hidden;
}

.container::before {
content: ”;
position: absolute;
top: -50%;
left: -50%;
width: 200%;
height: 200%;
background: radial-gradient(circle, rgba(255, 107, 107, 0.1) 0%, rgba(78, 205, 196, 0) 70%);
animation: rotate 20s linear infinite;
z-index: -1;
}

@keyframes rotate {
0% { transform: rotate(0deg); }
100% { transform: rotate(360deg); }
}

h1 {
font-size: 2.5rem;
margin-bottom: 30px;
color: var(–accent-color);
text-shadow: 0 3px 10px rgba(255, 230, 109, 0.4);
position: relative;
display: inline-block;
}

h1::after {
content: ”;
position: absolute;
bottom: -10px;
left: 0;
width: 100%;
height: 3px;
background: linear-gradient(90deg, var(–primary-color), var(–secondary-color));
border-radius: 3px;
}

.file-upload {
margin: 25px 0;
position: relative;
display: flex;
flex-direction: column;
align-items: center;
}

.file-upload label {
display: block;
margin-bottom: 10px;
font-size: 1.1rem;
color: var(–light-color);
}

.file-upload input[type=”file”] {
display: none;
}

.custom-file-upload {
border: 2px dashed rgba(255, 255, 255, 0.3);
border-radius: 10px;
padding: 15px 30px;
cursor: pointer;
transition: all 0.3s;
display: flex;
align-items: center;
justify-content: center;
background: rgba(255, 255, 255, 0.05);
width: 80%;
max-width: 300px;
}

.custom-file-upload:hover {
border-color: var(–accent-color);
background: rgba(255, 230, 109, 0.1);
}

.custom-file-upload i {
margin-right: 10px;
font-size: 1.5rem;
color: var(–accent-color);
}

#file-name {
margin-top: 10px;
font-size: 0.9rem;
color: var(–secondary-color);
}

#start-btn {
padding: 15px 40px;
font-size: 1.2rem;
cursor: pointer;
background: linear-gradient(45deg, var(–primary-color), var(–secondary-color));
color: var(–dark-color);
border: none;
border-radius: 50px;
margin: 20px 0;
font-weight: bold;
box-shadow: 0 5px 15px rgba(0, 0, 0, 0.2);
transition: all 0.3s;
position: relative;
overflow: hidden;
}

#start-btn:hover {
transform: translateY(-3px);
box-shadow: 0 8px 20px rgba(0, 0, 0, 0.3);
}

#start-btn:active {
transform: translateY(1px);
}

#start-btn::before {
content: ”;
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
background: linear-gradient(45deg, var(–secondary-color), var(–primary-color));
opacity: 0;
transition: opacity 0.3s;
}

#start-btn:hover::before {
opacity: 1;
}

#message {
font-size: 1.3rem;
color: var(–accent-color);
margin: 20px 0;
min-height: 30px;
text-shadow: 0 2px 5px rgba(255, 230, 109, 0.3);
}

#students {
font-size: 1.8rem;
font-weight: bold;
margin: 20px 0;
color: var(–light-color);
min-height: 50px;
display: flex;
align-items: center;
justify-content: center;
position: relative;
padding: 15px;
background: rgba(0, 0, 0, 0.2);
border-radius: 10px;
border-left: 3px solid var(–primary-color);
border-right: 3px solid var(–secondary-color);
}

.student-name {
animation: pulse 1s infinite alternate;
}

@keyframes pulse {
0% { transform: scale(1); }
100% { transform: scale(1.05); }
}

.confetti {
position: absolute;
width: 10px;
height: 10px;
background-color: var(–accent-color);
opacity: 0;
}

.music-control {
position: fixed;
bottom: 20px;
right: 20px;
background: rgba(41, 47, 54, 0.8);
border-radius: 50%;
width: 50px;
height: 50px;
display: flex;
align-items: center;
justify-content: center;
cursor: pointer;
box-shadow: 0 5px 15px rgba(0, 0, 0, 0.2);
z-index: 100;
border: 1px solid rgba(255, 255, 255, 0.1);
}

.music-control i {
font-size: 1.5rem;
color: var(–light-color);
}

.student-list {
max-height: 150px;
overflow-y: auto;
margin: 20px 0;
padding: 10px;
background: rgba(0, 0, 0, 0.2);
border-radius: 10px;
text-align: left;
}

.student-list div {
padding: 5px 10px;
margin: 3px 0;
background: rgba(255, 255, 255, 0.1);
border-radius: 5px;
display: inline-block;
margin-right: 5px;
}

/* 滚动条样式 */
.student-list::-webkit-scrollbar {
width: 5px;
}

.student-list::-webkit-scrollbar-track {
background: rgba(0, 0, 0, 0.1);
border-radius: 10px;
}

.student-list::-webkit-scrollbar-thumb {
background: var(–primary-color);
border-radius: 10px;
}

/* 响应式设计 */
@media (max-width: 600px) {
.container {
padding: 20px;
width: 95%;
}

h1 {
font-size: 2rem;
}

#students {
font-size: 1.5rem;
}
}
</style>
<link rel=”stylesheet” href=”https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.0.0-beta3/css/all.min.css”>
</head>
<body>
<div class=”container”>
<h1>击鼓传花游戏</h1>

<div class=”file-upload”>
<label for=”file-input”>选择学生名单文件</label>
<label class=”custom-file-upload”>
<i class=”fas fa-file-upload”></i>
<span>点击上传文件</span>
<input type=”file” id=”file-input” accept=”.txt,.csv”>
</label>
<div id=”file-name”>未选择文件</div>
</div>

<div class=”student-list” id=”student-list”></div>

<button id=”start-btn” disabled><i class=”fas fa-play”></i> 开始游戏</button>

<p id=”message”>请先上传学生名单</p>

<div id=”students”>
<span class=”student-name”>等待游戏开始…</span>
</div>
</div>

<div class=”music-control” id=”music-control”>
<i class=”fas fa-music”></i>
</div>

<!– 背景音乐 –>
<audio id=”bg-music” loop>
<source src=”击鼓传花鼓声.mp3″ type=”audio/mp3″>
您的浏览器不支持音频元素。
</audio>

<script>
let students = [];
let currentStudent = “”;
let timer;
let passInterval;
const music = document.getElementById(‘bg-music’);
const startButton = document.getElementById(‘start-btn’);
const musicControl = document.getElementById(‘music-control’);
const fileNameDisplay = document.getElementById(‘file-name’);
const studentList = document.getElementById(‘student-list’);

// 显示当前传递物品的学生
function showCurrentStudent() {
const studentElement = document.querySelector(‘.student-name’);
studentElement.textContent = currentStudent;

// 添加动画效果
studentElement.style.animation = ‘none’;
void studentElement.offsetWidth; // 触发重绘
studentElement.style.animation = ‘pulse 0.5s’;
}

// 随机选择一个学生
function getRandomStudent() {
return students[Math.floor(Math.random() * students.length)];
}

// 创建五彩纸屑效果
function createConfetti() {
const container = document.querySelector(‘.container’);
for (let i = 0; i < 50; i++) {
const confetti = document.createElement(‘div’);
confetti.classList.add(‘confetti’);
confetti.style.left = Math.random() * 100 + ‘%’;
confetti.style.top = -10 + ‘px’;
confetti.style.backgroundColor = getRandomColor();
confetti.style.transform = `rotate(\({Math.random() * 360}deg)`;
container.appendChild(confetti);

// 动画
const animation = confetti.animate([
{ top: ‘-10px’, opacity: 1, transform: `rotate(\){Math.random() * 360}deg)` },
{ top: ‘100%’, opacity: 0, transform: `rotate(\({Math.random() * 360}deg)` }
], {
duration: 2000 + Math.random() * 3000,
easing: ‘cubic-bezier(0.1, 0.8, 0.9, 1)’
});

animation.onfinish = () => confetti.remove();
}
}

function getRandomColor() {
const colors = [‘#ff6b6b’, ‘#4ecdc4’, ‘#ffe66d’, ‘#ff9ff3’, ‘#48dbfb’];
return colors[Math.floor(Math.random() * colors.length)];
}

// 播放音乐并开始传递
function startGame() {
currentStudent = getRandomStudent();
showCurrentStudent();
document.getElementById(‘message’).innerHTML = ‘<i class=”fas fa-music”></i> 音乐开始播放,请传递物品!’;
startButton.disabled = true;
startButton.innerHTML = ‘<i class=”fas fa-spinner fa-spin”></i> 游戏中…’;

// 播放背景音乐
music.play();
musicControl.innerHTML = ‘<i class=”fas fa-volume-up”></i>’;

// 模拟音乐播放
let musicDuration = Math.floor(Math.random() * 6) + 5; // 随机5到10秒
timer = setTimeout(endGame, musicDuration * 1000); // 设置游戏结束的时间

// 每1秒随机传递物品
passInterval = setInterval(() => {
currentStudent = getRandomStudent();
showCurrentStudent();
}, 1000);
}

// 游戏结束
function endGame() {
document.getElementById(‘message’).innerHTML = `<i class=”fas fa-trophy”></i> \){currentStudent},游戏结束,请回答问题!`;
music.pause(); // 停止背景音乐
startButton.disabled = false;
startButton.innerHTML = ‘<i class=”fas fa-redo”></i> 重新开始’;

// 显示五彩纸屑效果
createConfetti();
}

// 读取文本文件并更新学生名单
function readTextFile(file) {
const reader = new FileReader();
reader.onload = function(event) {
const contents = event.target.result;
const lines = contents.split(‘\n’);
students = lines.map(line => line.trim()).filter(line => line !== “”);

// 显示文件名
fileNameDisplay.textContent = file.name;
fileNameDisplay.style.color = ‘#4ecdc4’;

// 显示学生列表
studentList.innerHTML = ”;
students.forEach(student => {
const div = document.createElement(‘div’);
div.textContent = student;
studentList.appendChild(div);
});

if (students.length < 2) {
alert(“请至少输入两个学生的名字!”);
startButton.disabled = true;
} else {
startButton.disabled = false;
document.getElementById(‘message’).textContent = `已导入 ${students.length} 名学生,点击开始游戏`;
}
};
reader.readAsText(file);
}

// 监听文件上传事件
document.getElementById(‘file-input’).addEventListener(‘change’, function(event) {
const file = event.target.files[0];
if (file && (file.type === ‘text/plain’ || file.name.endsWith(‘.csv’))) {
readTextFile(file);
} else {
alert(“请上传有效的文本文件(.txt 或 .csv)!”);
}
});

// 绑定按钮点击事件
startButton.addEventListener(‘click’, () => {
if (students.length === 0) {
alert(“请先上传学生名单!”);
} else {
startGame();
}
});

// 音乐控制按钮
musicControl.addEventListener(‘click’, () => {
if (music.paused) {
music.play();
musicControl.innerHTML = ‘<i class=”fas fa-volume-up”></i>’;
} else {
music.pause();
musicControl.innerHTML = ‘<i class=”fas fa-volume-mute”></i>’;
}
});
</script>
</body>
</html>