anycoder-18578600 / index.html
xianbao's picture
Upload folder using huggingface_hub
7694999 verified
<!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;
}
:root {
--primary-color: #6366f1;
--secondary-color: #8b5cf6;
--success-color: #10b981;
--warning-color: #f59e0b;
--danger-color: #ef4444;
--dark-color: #1f2937;
--light-color: #f3f4f6;
--game-bg: #fef3c7;
--wall-color: #92400e;
--box-color: #d97706;
--box-on-target: #059669;
--target-color: #fbbf24;
--player-color: #3b82f6;
}
body {
font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
min-height: 100vh;
display: flex;
flex-direction: column;
align-items: center;
padding: 20px;
position: relative;
overflow-x: hidden;
}
body::before {
content: '';
position: absolute;
top: -50%;
left: -50%;
width: 200%;
height: 200%;
background: repeating-linear-gradient(45deg,
transparent,
transparent 10px,
rgba(255, 255, 255, 0.05) 10px,
rgba(255, 255, 255, 0.05) 20px);
animation: backgroundMove 20s linear infinite;
}
@keyframes backgroundMove {
0% {
transform: translate(0, 0);
}
100% {
transform: translate(50px, 50px);
}
}
header {
background: rgba(255, 255, 255, 0.95);
padding: 20px 40px;
border-radius: 20px;
box-shadow: 0 10px 30px rgba(0, 0, 0, 0.2);
margin-bottom: 30px;
text-align: center;
backdrop-filter: blur(10px);
position: relative;
z-index: 10;
}
h1 {
color: var(--primary-color);
font-size: 2.5rem;
margin-bottom: 10px;
text-shadow: 2px 2px 4px rgba(0, 0, 0, 0.1);
animation: titleBounce 2s ease-in-out infinite;
}
@keyframes titleBounce {
0%,
100% {
transform: translateY(0);
}
50% {
transform: translateY(-5px);
}
}
.subtitle {
color: var(--secondary-color);
font-size: 1.2rem;
margin-bottom: 15px;
}
.built-with {
color: var(--dark-color);
font-size: 0.9rem;
opacity: 0.7;
transition: opacity 0.3s;
}
.built-with:hover {
opacity: 1;
text-decoration: underline;
}
main {
background: rgba(255, 255, 255, 0.95);
padding: 30px;
border-radius: 20px;
box-shadow: 0 15px 40px rgba(0, 0, 0, 0.2);
max-width: 800px;
width: 100%;
backdrop-filter: blur(10px);
position: relative;
z-index: 10;
}
.level-selector {
display: none;
grid-template-columns: repeat(auto-fit, minmax(120px, 1fr));
gap: 15px;
margin-bottom: 30px;
}
.level-selector.active {
display: grid;
}
.level-btn {
background: linear-gradient(135deg, var(--primary-color), var(--secondary-color));
color: white;
border: none;
padding: 15px;
border-radius: 15px;
font-size: 1.1rem;
font-weight: bold;
cursor: pointer;
transition: all 0.3s ease;
position: relative;
overflow: hidden;
}
.level-btn::before {
content: '';
position: absolute;
top: 50%;
left: 50%;
width: 0;
height: 0;
background: rgba(255, 255, 255, 0.3);
border-radius: 50%;
transform: translate(-50%, -50%);
transition: width 0.6s, height 0.6s;
}
.level-btn:hover::before {
width: 300px;
height: 300px;
}
.level-btn:hover {
transform: translateY(-3px);
box-shadow: 0 10px 20px rgba(99, 102, 241, 0.3);
}
.level-btn:disabled {
opacity: 0.5;
cursor: not-allowed;
}
.level-btn.completed {
background: linear-gradient(135deg, var(--success-color), #059669);
}
.level-btn.current {
animation: pulse 2s infinite;
}
@keyframes pulse {
0% {
box-shadow: 0 0 0 0 rgba(99, 102, 241, 0.7);
}
70% {
box-shadow: 0 0 0 10px rgba(99, 102, 241, 0);
}
100% {
box-shadow: 0 0 0 0 rgba(99, 102, 241, 0);
}
}
.game-info {
display: flex;
justify-content: space-between;
align-items: center;
margin-bottom: 20px;
flex-wrap: wrap;
gap: 15px;
}
.info-item {
background: linear-gradient(135deg, #f3f4f6, #e5e7eb);
padding: 10px 20px;
border-radius: 10px;
display: flex;
align-items: center;
gap: 10px;
box-shadow: 0 2px 10px rgba(0, 0, 0, 0.1);
}
.info-label {
color: var(--dark-color);
font-weight: bold;
}
.info-value {
color: var(--primary-color);
font-size: 1.2rem;
font-weight: bold;
}
.game-container {
display: flex;
flex-direction: column;
align-items: center;
gap: 20px;
}
.game-board {
display: grid;
gap: 2px;
padding: 20px;
background: var(--game-bg);
border-radius: 15px;
box-shadow: inset 0 2px 10px rgba(0, 0, 0, 0.1);
position: relative;
}
.cell {
width: 50px;
height: 50px;
display: flex;
align-items: center;
justify-content: center;
font-size: 30px;
transition: all 0.3s ease;
position: relative;
}
.cell.wall {
background: linear-gradient(135deg, var(--wall-color), #78350f);
border-radius: 5px;
box-shadow: 0 2px 5px rgba(0, 0, 0, 0.3);
}
.cell.floor {
background: rgba(255, 255, 255, 0.3);
border-radius: 5px;
}
.cell.target {
background: var(--target-color);
border-radius: 50%;
animation: targetPulse 2s infinite;
}
@keyframes targetPulse {
0%,
100% {
transform: scale(1);
opacity: 0.8;
}
50% {
transform: scale(1.1);
opacity: 1;
}
}
.player {
animation: playerBounce 0.5s ease;
}
@keyframes playerBounce {
0%,
100% {
transform: translateY(0);
}
50% {
transform: translateY(-10px);
}
}
.box {
animation: boxMove 0.3s ease;
}
@keyframes boxMove {
0% {
transform: scale(1);
}
50% {
transform: scale(1.1);
}
100% {
transform: scale(1);
}
}
.box-on-target {
animation: successPulse 1s infinite;
}
@keyframes successPulse {
0%,
100% {
transform: scale(1) rotate(0deg);
}
50% {
transform: scale(1.1) rotate(5deg);
}
}
.controls {
display: flex;
gap: 10px;
justify-content: center;
flex-wrap: wrap;
}
.btn {
background: linear-gradient(135deg, var(--primary-color), var(--secondary-color));
color: white;
border: none;
padding: 12px 24px;
border-radius: 10px;
font-size: 1rem;
font-weight: bold;
cursor: pointer;
transition: all 0.3s ease;
display: flex;
align-items: center;
gap: 8px;
}
.btn:hover {
transform: translateY(-2px);
box-shadow: 0 5px 15px rgba(99, 102, 241, 0.3);
}
.btn:active {
transform: translateY(0);
}
.btn-secondary {
background: linear-gradient(135deg, #6b7280, #4b5563);
}
.btn-success {
background: linear-gradient(135deg, var(--success-color), #059669);
}
.btn-danger {
background: linear-gradient(135deg, var(--danger-color), #dc2626);
}
.arrow-keys {
display: grid;
grid-template-columns: repeat(3, 60px);
grid-template-rows: repeat(3, 60px);
gap: 5px;
margin-top: 20px;
}
.arrow-key {
background: linear-gradient(135deg, #e5e7eb, #d1d5db);
border: 2px solid #9ca3af;
border-radius: 10px;
font-size: 24px;
cursor: pointer;
transition: all 0.2s ease;
display: flex;
align-items: center;
justify-content: center;
}
.arrow-key:hover {
background: linear-gradient(135deg, var(--primary-color), var(--secondary-color));
border-color: var(--primary-color);
transform: scale(1.05);
}
.arrow-key:active {
transform: scale(0.95);
}
.arrow-key.up {
grid-column: 2;
grid-row: 1;
}
.arrow-key.left {
grid-column: 1;
grid-row: 2;
}
.arrow-key.down {
grid-column: 2;
grid-row: 2;
}
.arrow-key.right {
grid-column: 3;
grid-row: 2;
}
.win-message {
display: none;
position: fixed;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
background: white;
padding: 40px;
border-radius: 20px;
box-shadow: 0 20px 60px rgba(0, 0, 0, 0.3);
text-align: center;
z-index: 1000;
animation: winPop 0.5s ease;
}
@keyframes winPop {
0% {
transform: translate(-50%, -50%) scale(0);
}
50% {
transform: translate(-50%, -50%) scale(1.1);
}
100% {
transform: translate(-50%, -50%) scale(1);
}
}
.win-message.active {
display: block;
}
.win-title {
font-size: 2rem;
color: var(--success-color);
margin-bottom: 20px;
}
.stars {
font-size: 3rem;
margin-bottom: 20px;
animation: starSpin 1s ease;
}
@keyframes starSpin {
0% {
transform: rotate(0deg) scale(0);
}
100% {
transform: rotate(360deg) scale(1);
}
}
.overlay {
display: none;
position: fixed;
top: 0;
left: 0;
width: 100%;
height: 100%;
background: rgba(0, 0, 0, 0.5);
z-index: 999;
}
.overlay.active {
display: block;
}
@media (max-width: 768px) {
h1 {
font-size: 2rem;
}
.cell {
width: 40px;
height: 40px;
font-size: 24px;
}
.arrow-keys {
grid-template-columns: repeat(3, 50px);
grid-template-rows: repeat(3, 50px);
}
.game-board {
padding: 15px;
}
}
@media (max-width: 480px) {
.cell {
width: 30px;
height: 30px;
font-size: 18px;
}
.arrow-keys {
grid-template-columns: repeat(3, 40px);
grid-template-rows: repeat(3, 40px);
}
main {
padding: 20px;
}
}
</style>
</head>
<body>
<header>
<h1>🎮 推箱子大冒险 📦</h1>
<div class="subtitle">和小朋友一起玩益智游戏!</div>
<a href="https://huggingface.co/spaces/akhaliq/anycoder" target="_blank" class="built-with">
Built with anycoder
</a>
</header>
<main>
<div class="level-selector active" id="levelSelector">
<button class="level-btn" onclick="startLevel(0)">关卡 1<br>🌱 简单</button>
<button class="level-btn" onclick="startLevel(1)">关卡 2<br>🌿 简单</button>
<button class="level-btn" onclick="startLevel(2)">关卡 3<br>🍀 中等</button>
<button class="level-btn" onclick="startLevel(3)">关卡 4<br>🌳 中等</button>
<button class="level-btn" onclick="startLevel(4)">关卡 5<br>🌲 困难</button>
<button class="level-btn" onclick="startLevel(5)">关卡 6<br>🎄 困难</button>
</div>
<div class="game-container" id="gameContainer" style="display: none;">
<div class="game-info">
<div class="info-item">
<span class="info-label">关卡:</span>
<span class="info-value" id="currentLevel">1</span>
</div>
<div class="info-item">
<span class="info-label">步数:</span>
<span class="info-value" id="moveCount">0</span>
</div>
<div class="info-item">
<span class="info-label">最佳:</span>
<span class="info-value" id="bestScore">-</span>
</div>
</div>
<div class="game-board" id="gameBoard"></div>
<div class="controls">
<button class="btn btn-secondary" onclick="undoMove()">
↶ 撤销
</button>
<button class="btn btn-danger" onclick="resetLevel()">
🔄 重置
</button>
<button class="btn btn-success" onclick="backToMenu()">
📋 选关
</button>
</div>
<div class="arrow-keys">
<button class="arrow-key up" onclick="movePlayer('up')"></button>
<button class="arrow-key left" onclick="movePlayer('left')"></button>
<button class="arrow-key down" onclick="movePlayer('down')"></button>
<button class="arrow-key right" onclick="movePlayer('right')"></button>
</div>
</div>
</main>
<div class="overlay" id="overlay"></div>
<div class="win-message" id="winMessage">
<div class="win-title">🎉 恭喜过关!</div>
<div class="stars">⭐⭐⭐</div>
<div style="margin-bottom: 20px;">
用了 <span id="finalMoves" style="color: var(--primary-color); font-weight: bold;">0</span> 步完成!
</div>
<div class="controls" style="justify-content: center;">
<button class="btn btn-success" onclick="nextLevel()">下一关</button>
<button class="btn btn-secondary" onclick="backToMenu()">选关菜单</button>
</div>
</div>
<script>
// 游戏数据
const levels = [
{
name: "入门练习",
width: 7,
height: 7,
map: [
"#######",
"# #",
"# $@$.#",
"# $ #",
"# . #",
"# #",
"#######"
]
},
{
name: "双箱挑战",
width: 8,
height: 7,
map: [
"########",
"# . #",
"# $@$. #",
"# $ #",
"# . #",
"# #",
"########"
]
},
{
name: "转角遇到爱",
width: 9,
height: 8,
map: [
"#########",
"# # #",
"# $ @ $ #",
"# . # . #",
"# # #",
"# $ $ #",
"# . . #",
"#########"
]
},
{
name: "迷宫探险",
width: 10,
height: 8,
map: [
"##########",
"# # #",
"# $ @ $ #",
"# . # . #",
"# # #",
"# $ $ #",
"# . . #",
"##########"
]
},
{
name: "极限挑战",
width: 11,
height: 9,
map: [
"###########",
"# # #",
"# $ @ $ #",
"# . # . #",
"# # #",
"# $ $ $ #",
"# . . . . #",
"# #",
"###########"
]
},
{
name: "终极考验",
width: 12,
height: 10,
map: [
"############",
"# # #",
"# $ @ $ #",
"# . # . #",
"# # #",
"# $ $ $ #",
"# . . . . . #",
"# # #",
"# $ $ $ #",
"############"
]
}
];
let currentLevelIndex = 0;
let gameState = null;
let moveHistory = [];
let completedLevels = JSON.parse(localStorage.getItem('completedLevels') || '[]');
let bestScores = JSON.parse(localStorage.getItem('bestScores') || '{}');
// 初始化
function init() {
updateLevelButtons();
setupKeyboardControls();
}
// 更新关卡按钮状态
function updateLevelButtons() {
const buttons = document.querySelectorAll('.level-btn');
buttons.forEach((btn, index) => {
if (completedLevels.includes(index)) {
btn.classList.add('completed');
} else {
btn.classList.remove('completed');
}
});
}
// 开始关卡
function startLevel(levelIndex) {
currentLevelIndex = levelIndex;
const level = levels[levelIndex];
gameState = {
map: JSON.parse(JSON.stringify(level.map)),
playerPos: findPlayer(level.map),
boxes: findBoxes(level.map),
targets: findTargets(level.map),
moveCount: 0
};
moveHistory = [];
document.getElementById('levelSelector').classList.remove('active');
document.getElementById('gameContainer').style.display = 'flex';
document.getElementById('currentLevel').textContent = levelIndex + 1;
document.getElementById('moveCount').textContent = '0';
document.getElementById('bestScore').textContent = bestScores[levelIndex] || '-';
renderGame();
}
// 渲染游戏
function renderGame() {
const board = document.getElementById('gameBoard');
const level = levels[currentLevelIndex];
board.style.gridTemplateColumns = `repeat(${level.width}, 1fr)`;
board.innerHTML = '';
for (let y = 0; y < level.height; y++) {
for (let x = 0; x < level.width; x++) {
const cell = document.createElement('div');
cell.className = 'cell';
const char = gameState.map[y][x];
const isTarget = gameState.targets.some(t => t.x === x && t.y === y);
const hasBox = gameState.boxes.some(b => b.x === x && b.y === y);
const isPlayer = gameState.playerPos.x === x && gameState.playerPos.y === y;
if (char === '#') {
cell.classList.add('wall');
cell.textContent = '🧱';
} else if (isTarget && !hasBox && !isPlayer) {
cell.classList.add('target');
cell.textContent = '🎯';
} else {
cell.classList.add('floor');
if (hasBox) {
cell.classList.add('box');
if (isTarget) {
cell.classList.add('box-on-target');
cell.textContent = '✅';
} else {
cell.textContent = '📦';
}
} else if (isPlayer) {
cell.classList.add('player');
cell.textContent = '🤖';
}
}
board.appendChild(cell);
}
}
}
// 查找玩家位置
function findPlayer(map) {
for (let y = 0; y < map.length; y++) {
for (let x = 0; x < map[y].length; x++) {
if (map[y][x] === '@') {
return { x, y };
}
}
}
return null;
}
// 查找箱子位置
function findBoxes(map) {
const boxes = [];
for (let y = 0; y < map.length; y++) {
for (let x = 0; x < map[y].length; x++) {
if (map[y][x] === '$') {
boxes.push({ x, y });
}
}
}
return boxes;
}
// 查找目标位置
function findTargets(map) {
const targets = [];
for (let y = 0; y < map.length; y++) {
for (let x = 0; x < map[y].length; x++) {
if (map[y][x] === '.') {
targets.push({ x, y });
}
}
}
return targets;
}
// 移动玩家
function movePlayer(direction) {
if (!gameState) return;
const dirs = {
'up': { x: 0, y: -1 },
'down': { x: 0, y: 1 },
'left': { x: -1, y: 0 },
'right': { x: 1, y: 0 }
};
const dir = dirs[direction];
const newPos = {
x: gameState.playerPos.x + dir.x,
y: gameState.playerPos.y + dir.y
};
// 保存历史
const history = {
playerPos: { ...gameState.playerPos },
boxes: gameState.boxes.map(b => ({ ...b })),
moveCount: gameState.moveCount
};
// 检查是否撞墙
if (gameState.map[newPos.y][newPos.x] === '#') {
return;
}
// 检查是否有箱子
const boxIndex = gameState.boxes.findIndex(b => b.x === newPos.x && b.y === newPos.y);
if (boxIndex !== -1) {
const newBoxPos = {
x: newPos.x + dir.x,
y: newPos.y + dir.y
};
// 检查箱子是否能移动
if (gameState.map[newBoxPos.y][newBoxPos.x] === '#') {
return;
}
// 检查是否有其他箱子
if (gameState.boxes.some(b => b.x === newBoxPos.x && b.y === newBoxPos.y)) {
return;
}
// 移动箱子
gameState.boxes[boxIndex] = newBoxPos;
moveHistory.push(history);
gameState.playerPos = newPos;
gameState.moveCount++;
} else {
// 只移动玩家
moveHistory.push(history);
gameState.playerPos = newPos;
gameState.moveCount++;
}
document.getElementById('moveCount').textContent = gameState.moveCount;
renderGame();
// 检查是否获胜
if (checkWin()) {
setTimeout(() => showWinMessage(), 500);
}
}
// 检查是否获胜
function checkWin() {
return gameState.targets.every(target =>
gameState.boxes.some(box => box.x === target.x && box.y === target.y)
);
}
// 显示获胜消息
function showWinMessage() {
if (!completedLevels.includes(currentLevelIndex)) {
completedLevels.push(currentLevelIndex);
localStorage.setItem('completedLevels', JSON.stringify(completedLevels));
}
if (!bestScores[currentLevelIndex] || gameState.moveCount < bestScores[currentLevelIndex]) {
bestScores[currentLevelIndex] = gameState.moveCount;
localStorage.setItem('bestScores', JSON.stringify(bestScores));
}
document.getElementById('finalMoves').textContent = gameState.moveCount;
document.getElementById('overlay').classList.add('active');
document.getElementById('winMessage').classList.add('active');
}
// 下一关
function nextLevel() {
document.getElementById('overlay').classList.remove('active');
document.getElementById('winMessage').classList.remove('active');
if (currentLevelIndex < levels.length - 1) {
startLevel(currentLevelIndex + 1);
} else {
backToMenu();
}
}
// 撤销移动
function undoMove() {
if (moveHistory.length === 0) return;
const history = moveHistory.pop();
gameState.playerPos = history.playerPos;
gameState.boxes = history.boxes;
gameState.moveCount = history.moveCount;
document.getElementById('moveCount').textContent = gameState.moveCount;
renderGame();
}
// 重置关卡
function resetLevel() {
startLevel(currentLevelIndex);
}
// 返回菜单
function backToMenu() {
document.getElementById('overlay').classList.remove('active');
document.getElementById('winMessage').classList.remove('active');
document.getElementById('levelSelector').classList.add('active');
document.getElementById('gameContainer').style.display = 'none';
updateLevelButtons();
}
// 设置键盘控制
function setupKeyboardControls() {
document.addEventListener('keydown', (e) => {
if (!gameState) return;
const keyMap = {
'ArrowUp': 'up',
'ArrowDown': 'down',
'ArrowLeft': 'left',
'ArrowRight': 'right',
'w': 'up',
's': 'down',
'a': 'left',
'd': 'right',
'W': 'up',
'S': 'down',
'A': 'left',
'D': 'right'
};
if (keyMap[e.key]) {
e.preventDefault();
movePlayer(keyMap[e.key]);
}
if (e.key === 'z' || e.key === 'Z') {
undoMove();
}
if (e.key === 'r' || e.key === 'R') {
resetLevel();
}
});
}
// 启动游戏
init();
</script>
</body>
</html>