Files
RGKT/rg-09112127/html/play/美味餐桌01(4以内加法).html
2025-10-10 19:44:14 +08:00

507 lines
15 KiB
HTML
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>美味餐桌4以内加法</title>
<!-- 引入后端集成脚本 -->
<script src="../../js/apiService.js"></script>
<script src="../../js/dataManager.js"></script>
<script src="../../js/userManager.js"></script>
<script src="../../js/accessTracker.js"></script>
<script src="../../js/gameTracker.js"></script>
<script src="../../js/gameDataLogger.js"></script>
<style>
/* 基础样式 */
:root {
--primary: #FF9AA2;
/* 粉色 */
--secondary: #FFB7B2;
/* 浅粉色 */
--accent: #FFDAC1;
/* 米色 */
--food: #E2F0CB;
/* 浅绿色 */
--text: #5E5346;
/* 棕色 */
--correct: #B5EAD7;
/* 浅绿色 */
--wrong: #FF9AA2;
/* 粉色 */
}
* {
margin: 0;
padding: 0;
box-sizing: border-box;
}
body {
font-family: 'Comic Sans MS', 'Marker Felt', '微软雅黑', sans-serif;
background-color: var(--accent);
color: var(--text);
min-height: 100vh;
display: flex;
flex-direction: column;
align-items: center;
padding: 20px;
}
h1 {
color: var(--primary);
margin-bottom: 20px;
text-shadow: 2px 2px 0px rgba(0, 0, 0, 0.1);
font-size: 2.2rem;
}
.container {
width: 100%;
max-width: 800px;
background-color: white;
border-radius: 20px;
padding: 20px;
box-shadow: 0 8px 16px rgba(0, 0, 0, 0.1);
text-align: center;
}
/* 餐桌区域 */
.table-area {
background-color: #F0E6DD;
border: 12px solid #D4A76A;
border-radius: 50%;
width: 100%;
height: 250px;
margin-bottom: 30px;
display: flex;
justify-content: center;
align-items: center;
position: relative;
overflow: hidden;
}
.table-area::before {
content: "";
position: absolute;
top: 0;
left: 0;
right: 0;
bottom: 0;
background: radial-gradient(circle at center, transparent 60%, rgba(0, 0, 0, 0.1) 100%);
}
.table-items {
display: flex;
flex-wrap: wrap;
justify-content: center;
gap: 15px;
padding: 20px;
width: 100%;
height: 100%;
align-items: center;
}
/* 美食区域 */
.food-area {
display: flex;
flex-wrap: wrap;
justify-content: center;
gap: 15px;
padding: 30px;
background-color: var(--secondary);
border-radius: 15px;
min-height: 150px;
}
/* 美食图片样式 */
.food-item {
width: 80px;
height: 80px;
background-color: var(--food);
border-radius: 50%;
display: flex;
justify-content: center;
align-items: center;
cursor: grab;
user-select: none;
transition: all 0.3s ease;
position: relative;
box-shadow: 0 4px 8px rgba(0, 0, 0, 0.1);
border: 3px solid white;
}
.food-item img {
width: 60px;
height: 60px;
object-fit: contain;
}
.food-item.dragging {
opacity: 0.8;
transform: scale(1.1);
box-shadow: 0 6px 12px rgba(0, 0, 0, 0.2);
}
/* 按钮样式 */
.btn {
background-color: var(--primary);
color: white;
border: none;
border-radius: 50px;
padding: 12px 25px;
font-size: 1.2rem;
margin: 10px auto;
cursor: pointer;
transition: all 0.3s ease;
box-shadow: 0 4px 8px rgba(0, 0, 0, 0.1);
}
.btn:hover {
transform: translateY(-3px);
box-shadow: 0 6px 12px rgba(0, 0, 0, 0.15);
}
.btn:active {
transform: translateY(1px);
}
/* 提示信息 */
.message {
margin-top: 15px;
padding: 10px 15px;
border-radius: 10px;
font-size: 1.2rem;
text-align: center;
opacity: 0;
transition: opacity 0.3s ease;
}
.message.show {
opacity: 1;
}
.correct {
background-color: var(--correct);
}
.wrong {
background-color: var(--wrong);
}
/* 动画效果 */
@keyframes shake {
0%,
100% {
transform: translateX(0);
}
25% {
transform: translateX(-5px);
}
75% {
transform: translateX(5px);
}
}
.shake {
animation: shake 0.3s ease infinite;
}
@keyframes float {
0%,
100% {
transform: translateY(0);
}
50% {
transform: translateY(-10px);
}
}
.float {
animation: float 2s ease-in-out infinite;
}
/* 庆祝效果 */
.celebration {
position: fixed;
top: 0;
left: 0;
width: 100%;
height: 100%;
pointer-events: none;
z-index: 100;
display: flex;
justify-content: center;
align-items: center;
opacity: 0;
transition: opacity 0.5s ease;
}
.celebration.show {
opacity: 1;
}
.confetti {
position: absolute;
width: 15px;
height: 15px;
background-color: var(--primary);
opacity: 0;
}
@keyframes confetti-fall {
0% {
transform: translateY(-100vh) rotate(0deg);
opacity: 1;
}
100% {
transform: translateY(100vh) rotate(360deg);
opacity: 0;
}
}
/* 响应式设计 */
@media (max-width: 600px) {
h1 {
font-size: 1.8rem;
}
.table-area {
height: 200px;
}
.food-item {
width: 70px;
height: 70px;
}
.food-item img {
width: 50px;
height: 50px;
}
}
</style>
</head>
<body>
<h1>美味餐桌</h1>
<div class="container">
<div class="table-area" id="tableArea">
<div class="table-items" id="tableItems"></div>
</div>
<div class="food-area" id="foodArea"></div>
<button class="btn" id="submitBtn">提交</button>
<div class="message correct show" id="message">请拖动下方美食放置到餐桌上,让餐桌上有四个美食。</div>
</div>
<div class="celebration" id="celebration">
</div>
<script>
// 美食图片数组
const foodImages = [
'🍎', '🍐', '🍊', '🍋', '🍌', '🍉', '🍇', '🍓', '🍈', '🍒', '🍑', '🥭', '🍍', '🥥', '🥝', '🍅', '🥑', '🥦', '🥕'
];
// DOM元素
const tableArea = document.getElementById('tableArea');
const tableItems = document.getElementById('tableItems');
const foodArea = document.getElementById('foodArea');
const submitBtn = document.getElementById('submitBtn');
const message = document.getElementById('message');
const celebration = document.getElementById('celebration');
// 游戏状态
let initialFoodCount = 0;
let draggedItems = [];
// 初始化游戏
function initGame() {
// 清空餐桌和美食区
tableItems.innerHTML = '';
foodArea.innerHTML = '';
// message.classList.remove('show');
// 随机生成1-3个初始美食
initialFoodCount = Math.floor(Math.random() * 3) + 1;
// 在餐桌上放置初始美食
for (let i = 0; i < initialFoodCount; i++) {
const randomFood = getRandomFood();
const foodItem = createFoodItem(randomFood, false);
tableItems.appendChild(foodItem);
}
// 在美食区放置4个随机美食
for (let i = 0; i < 4; i++) {
const randomFood = getRandomFood();
const foodItem = createFoodItem(randomFood, true);
foodArea.appendChild(foodItem);
}
// 重置拖动记录
draggedItems = [];
}
// 获取随机美食
function getRandomFood() {
const randomIndex = Math.floor(Math.random() * foodImages.length);
return foodImages[randomIndex];
}
// 创建美食元素
function createFoodItem(food, isDraggable) {
const foodItem = document.createElement('div');
foodItem.className = 'food-item float';
foodItem.innerHTML = `<span style="font-size: 2.5rem">${food}</span>`;
if (isDraggable) {
foodItem.draggable = true;
// 拖动开始
foodItem.addEventListener('dragstart', (e) => {
e.dataTransfer.setData('text/plain', food);
foodItem.classList.add('dragging');
setTimeout(() => {
foodItem.style.display = 'none';
}, 0);
});
// 拖动结束
foodItem.addEventListener('dragend', () => {
foodItem.classList.remove('dragging');
foodItem.style.display = 'flex';
});
}
return foodItem;
}
// 优化后的拖动放置逻辑
tableArea.addEventListener('dragover', (e) => {
e.preventDefault();
// 添加视觉效果提示可以放置
tableArea.style.boxShadow = 'inset 0 0 20px rgba(255, 154, 162, 0.5)';
});
tableArea.addEventListener('dragleave', () => {
// 移除视觉效果
tableArea.style.boxShadow = 'none';
});
tableArea.addEventListener('drop', (e) => {
e.preventDefault();
// 移除视觉效果
tableArea.style.boxShadow = 'none';
const food = e.dataTransfer.getData('text/plain');
// 创建美食并添加到餐桌
const foodItem = createFoodItem(food, false);
tableItems.appendChild(foodItem);
// 记录拖动的美食
draggedItems.push(food);
});
// 提交答案
submitBtn.addEventListener('click', () => {
const totalFood = initialFoodCount + draggedItems.length;
// 详细数据打印
console.log('🎯 美味餐桌游戏 - 提交答案记录');
console.log('📊 答案信息:', {
初始美食数量: initialFoodCount,
拖拽美食数量: draggedItems.length,
总美食数量: totalFood,
正确答案: 4,
是否正确: totalFood === 4 ? '✅ 正确' : '❌ 错误',
提交时间: new Date().toLocaleString('zh-CN')
});
console.log('📈 游戏进度:', {
拖拽的美食: draggedItems,
操作次数: draggedItems.length
});
// 清除之前的提示和动画
message.classList.remove('show');
document.querySelectorAll('.shake').forEach(el => {
el.classList.remove('shake');
});
if (totalFood === 4) {
// 答案正确
message.textContent = '太棒了正好4个美食';
message.className = 'message correct show';
celebrate();
} else if (totalFood < 4) {
// 美食不足
const needed = 4 - totalFood;
message.textContent = `还有我们呀!还需要${needed}个美食~`;
message.className = 'message wrong show';
// 让美食区的美食抖动
const foodItems = foodArea.querySelectorAll('.food-item');
for (let i = 0; i < needed && i < foodItems.length; i++) {
foodItems[i].classList.add('shake');
}
} else {
// 美食过多
const extra = totalFood - 4;
message.textContent = '吃不下这么多呢!太多了~';
message.className = 'message wrong show';
// 让餐桌上多余的美食抖动
const tableFoods = tableItems.querySelectorAll('.food-item');
for (let i = tableFoods.length - 1; i >= tableFoods.length - extra; i--) {
tableFoods[i].classList.add('shake');
}
}
// 3秒后重新开始游戏
setTimeout(initGame, 3000);
});
// 庆祝效果
function celebrate() {
celebration.innerHTML = '';
celebration.classList.add('show');
// 创建彩色纸屑
for (let i = 0; i < 50; i++) {
const confetti = document.createElement('div');
confetti.className = 'confetti';
confetti.style.left = `${Math.random() * 100}vw`;
confetti.style.backgroundColor = getRandomColor();
confetti.style.animation = `confetti-fall ${Math.random() * 2 + 2}s linear forwards`;
confetti.style.animationDelay = `${Math.random() * 0.5}s`;
celebration.appendChild(confetti);
}
// 3秒后隐藏庆祝效果
setTimeout(() => {
celebration.classList.remove('show');
}, 3000);
}
// 获取随机颜色
function getRandomColor() {
const colors = ['#FF9AA2', '#FFB7B2', '#FFDAC1', '#E2F0CB', '#B5EAD7', '#C7CEEA'];
return colors[Math.floor(Math.random() * colors.length)];
}
// 初始化游戏
initGame();
</script>
</body>
</html>