Spaces:
Running
Running
| <html lang="zh-CN"> | |
| <head> | |
| <meta charset="UTF-8"> | |
| <meta name="viewport" content="width=device-width, initial-scale=1.0"> | |
| <title>贪吃蛇小游戏</title> | |
| <script src="https://cdn.tailwindcss.com"></script> | |
| <style> | |
| /* 自定义样式 */ | |
| .game-container { | |
| position: relative; | |
| width: 100%; | |
| max-width: 600px; | |
| margin: 0 auto; | |
| aspect-ratio: 1/1; | |
| background-color: #f0f0f0; | |
| border-radius: 8px; | |
| overflow: hidden; | |
| box-shadow: 0 4px 6px rgba(0, 0, 0, 0.1); | |
| } | |
| .game-board { | |
| display: grid; | |
| grid-template-columns: repeat(20, 1fr); | |
| grid-template-rows: repeat(20, 1fr); | |
| width: 100%; | |
| height: 100%; | |
| } | |
| .snake { | |
| background-color: #4f46e5; | |
| border-radius: 2px; | |
| transition: all 0.1s ease; | |
| } | |
| .snake-head { | |
| background-color: #3730a3; | |
| border-radius: 4px; | |
| } | |
| .food { | |
| background-color: #ef4444; | |
| border-radius: 50%; | |
| animation: pulse 1s infinite; | |
| } | |
| @keyframes pulse { | |
| 0% { transform: scale(0.9); } | |
| 50% { transform: scale(1.1); } | |
| 100% { transform: scale(0.9); } | |
| } | |
| .game-overlay { | |
| position: absolute; | |
| top: 0; | |
| left: 0; | |
| right: 0; | |
| bottom: 0; | |
| background-color: rgba(0, 0, 0, 0.7); | |
| display: flex; | |
| flex-direction: column; | |
| justify-content: center; | |
| align-items: center; | |
| color: white; | |
| z-index: 10; | |
| } | |
| .control-btn { | |
| width: 60px; | |
| height: 60px; | |
| border-radius: 50%; | |
| background-color: rgba(255, 255, 255, 0.2); | |
| display: flex; | |
| justify-content: center; | |
| align-items: center; | |
| font-size: 24px; | |
| cursor: pointer; | |
| transition: all 0.2s; | |
| } | |
| .control-btn:hover { | |
| background-color: rgba(255, 255, 255, 0.3); | |
| } | |
| .control-btn:active { | |
| transform: scale(0.95); | |
| } | |
| </style> | |
| </head> | |
| <body class="bg-gray-100 min-h-screen flex flex-col items-center justify-start p-4 overflow-hidden"> | |
| <div class="text-center mb-6"> | |
| <h1 class="text-3xl font-bold text-gray-800 mb-2">贪吃蛇小游戏</h1> | |
| <div class="flex items-center justify-center space-x-4"> | |
| <div class="bg-white rounded-lg px-4 py-2 shadow"> | |
| <span class="text-gray-600">分数: </span> | |
| <span id="score" class="font-bold text-indigo-600">0</span> | |
| </div> | |
| <div class="bg-white rounded-lg px-4 py-2 shadow"> | |
| <span class="text-gray-600">最高分: </span> | |
| <span id="high-score" class="font-bold text-indigo-600">0</span> | |
| </div> | |
| </div> | |
| </div> | |
| <div class="game-container"> | |
| <div id="game-board" class="game-board"></div> | |
| <div id="game-overlay" class="game-overlay hidden"> | |
| <h2 class="text-3xl font-bold mb-4">游戏结束!</h2> | |
| <p class="text-xl mb-6">你的分数: <span id="final-score" class="font-bold">0</span></p> | |
| <button id="restart-btn" class="bg-indigo-600 hover:bg-indigo-700 text-white font-bold py-2 px-6 rounded-lg transition"> | |
| 重新开始 | |
| </button> | |
| </div> | |
| </div> | |
| <div class="mt-4 flex flex-wrap justify-center gap-4"> | |
| <button id="start-btn" class="bg-green-600 hover:bg-green-700 text-white font-bold py-2 px-6 rounded-lg transition"> | |
| 开始游戏 | |
| </button> | |
| <button id="pause-btn" class="bg-yellow-500 hover:bg-yellow-600 text-white font-bold py-2 px-6 rounded-lg transition hidden"> | |
| 暂停 | |
| </button> | |
| <div class="flex items-center bg-white rounded-lg px-4 py-2 shadow"> | |
| <label for="wall-mode" class="mr-2 text-gray-600">穿墙模式:</label> | |
| <input type="checkbox" id="wall-mode" class="w-4 h-4 text-indigo-600 rounded"> | |
| </div> | |
| </div> | |
| <div class="mt-8 text-gray-600 text-sm"> | |
| <p>使用键盘方向键控制蛇的移动</p> | |
| </div> | |
| <script> | |
| // 游戏变量 | |
| let snake = []; | |
| let food = {}; | |
| let direction = 'right'; | |
| let nextDirection = 'right'; | |
| let gameInterval; | |
| let gameSpeed = 150; | |
| let score = 0; | |
| let highScore = localStorage.getItem('snakeHighScore') || 0; | |
| let isPaused = false; | |
| let isGameOver = false; | |
| let wallMode = false; | |
| // DOM元素 | |
| const gameBoard = document.getElementById('game-board'); | |
| const scoreDisplay = document.getElementById('score'); | |
| const highScoreDisplay = document.getElementById('high-score'); | |
| const finalScoreDisplay = document.getElementById('final-score'); | |
| const gameOverlay = document.getElementById('game-overlay'); | |
| const startBtn = document.getElementById('start-btn'); | |
| const pauseBtn = document.getElementById('pause-btn'); | |
| const restartBtn = document.getElementById('restart-btn'); | |
| // 初始化游戏 | |
| function initGame() { | |
| // 清空游戏板 | |
| gameBoard.innerHTML = ''; | |
| // 初始化蛇 | |
| snake = [ | |
| {x: 10, y: 10}, | |
| {x: 9, y: 10}, | |
| {x: 8, y: 10} | |
| ]; | |
| // 初始化方向 | |
| direction = 'right'; | |
| nextDirection = 'right'; | |
| // 生成食物 | |
| generateFood(); | |
| // 重置分数 | |
| score = 0; | |
| scoreDisplay.textContent = score; | |
| highScoreDisplay.textContent = highScore; | |
| // 重置游戏状态 | |
| isPaused = false; | |
| isGameOver = false; | |
| // 隐藏游戏结束界面 | |
| gameOverlay.classList.add('hidden'); | |
| // 绘制游戏 | |
| drawGame(); | |
| } | |
| // 绘制游戏 | |
| function drawGame() { | |
| // 清空游戏板 | |
| gameBoard.innerHTML = ''; | |
| // 绘制蛇 | |
| snake.forEach((segment, index) => { | |
| const snakeElement = document.createElement('div'); | |
| snakeElement.classList.add(index === 0 ? 'snake-head' : 'snake'); | |
| snakeElement.style.gridColumn = segment.x; | |
| snakeElement.style.gridRow = segment.y; | |
| gameBoard.appendChild(snakeElement); | |
| }); | |
| // 绘制食物 | |
| const foodElement = document.createElement('div'); | |
| foodElement.classList.add('food'); | |
| foodElement.style.gridColumn = food.x; | |
| foodElement.style.gridRow = food.y; | |
| gameBoard.appendChild(foodElement); | |
| } | |
| // 生成食物 | |
| function generateFood() { | |
| // 随机生成食物位置 | |
| food = { | |
| x: Math.floor(Math.random() * 20) + 1, | |
| y: Math.floor(Math.random() * 20) + 1 | |
| }; | |
| // 确保食物不会出现在蛇身上 | |
| for (let segment of snake) { | |
| if (segment.x === food.x && segment.y === food.y) { | |
| return generateFood(); | |
| } | |
| } | |
| } | |
| // 游戏主循环 | |
| function gameLoop() { | |
| if (isPaused || isGameOver) return; | |
| // 更新方向 | |
| direction = nextDirection; | |
| // 获取蛇头 | |
| const head = {...snake[0]}; | |
| // 根据方向移动蛇头 | |
| switch (direction) { | |
| case 'up': | |
| head.y -= 1; | |
| break; | |
| case 'down': | |
| head.y += 1; | |
| break; | |
| case 'left': | |
| head.x -= 1; | |
| break; | |
| case 'right': | |
| head.x += 1; | |
| break; | |
| } | |
| // 检查是否撞墙 | |
| if (!wallMode && (head.x < 1 || head.x > 20 || head.y < 1 || head.y > 20)) { | |
| gameOver(); | |
| return; | |
| } | |
| // 穿墙处理 | |
| if (wallMode) { | |
| if (head.x < 1) head.x = 20; | |
| if (head.x > 20) head.x = 1; | |
| if (head.y < 1) head.y = 20; | |
| if (head.y > 20) head.y = 1; | |
| } | |
| // 检查是否撞到自己 | |
| for (let segment of snake) { | |
| if (segment.x === head.x && segment.y === head.y) { | |
| gameOver(); | |
| return; | |
| } | |
| } | |
| // 移动蛇 | |
| snake.unshift(head); | |
| // 检查是否吃到食物 | |
| if (head.x === food.x && head.y === food.y) { | |
| // 增加分数 | |
| score += 10; | |
| scoreDisplay.textContent = score; | |
| // 更新最高分 | |
| if (score > highScore) { | |
| highScore = score; | |
| highScoreDisplay.textContent = highScore; | |
| localStorage.setItem('snakeHighScore', highScore); | |
| } | |
| // 生成新食物 | |
| generateFood(); | |
| // 加快游戏速度 | |
| if (gameSpeed > 50 && score % 50 === 0) { | |
| gameSpeed -= 5; | |
| clearInterval(gameInterval); | |
| gameInterval = setInterval(gameLoop, gameSpeed); | |
| } | |
| } else { | |
| // 如果没有吃到食物,移除蛇尾 | |
| snake.pop(); | |
| } | |
| // 重新绘制游戏 | |
| drawGame(); | |
| } | |
| // 游戏结束 | |
| function gameOver() { | |
| clearInterval(gameInterval); | |
| isGameOver = true; | |
| finalScoreDisplay.textContent = score; | |
| gameOverlay.classList.remove('hidden'); | |
| } | |
| // 开始游戏 | |
| function startGame() { | |
| initGame(); | |
| gameInterval = setInterval(gameLoop, gameSpeed); | |
| startBtn.classList.add('hidden'); | |
| pauseBtn.classList.remove('hidden'); | |
| } | |
| // 暂停游戏 | |
| function togglePause() { | |
| isPaused = !isPaused; | |
| pauseBtn.textContent = isPaused ? '继续' : '暂停'; | |
| } | |
| // 事件监听器 | |
| startBtn.addEventListener('click', startGame); | |
| pauseBtn.addEventListener('click', togglePause); | |
| restartBtn.addEventListener('click', startGame); | |
| // 键盘控制 | |
| document.addEventListener('keydown', (e) => { | |
| // 阻止方向键默认行为 | |
| if (['ArrowUp', 'ArrowDown', 'ArrowLeft', 'ArrowRight', ' '].includes(e.key)) { | |
| e.preventDefault(); | |
| } | |
| switch (e.key) { | |
| case 'ArrowUp': | |
| if (direction !== 'down') nextDirection = 'up'; | |
| break; | |
| case 'ArrowDown': | |
| if (direction !== 'up') nextDirection = 'down'; | |
| break; | |
| case 'ArrowLeft': | |
| if (direction !== 'right') nextDirection = 'left'; | |
| break; | |
| case 'ArrowRight': | |
| if (direction !== 'left') nextDirection = 'right'; | |
| break; | |
| case ' ': | |
| if (!isGameOver) togglePause(); | |
| break; | |
| } | |
| }); | |
| // 穿墙模式切换 | |
| document.getElementById('wall-mode').addEventListener('change', (e) => { | |
| wallMode = e.target.checked; | |
| }); | |
| // 初始化显示 | |
| highScoreDisplay.textContent = highScore; | |
| </script> | |
| <p style="border-radius: 8px; text-align: center; font-size: 12px; color: #fff; margin-top: 16px;position: fixed; left: 8px; bottom: 8px; z-index: 10; background: rgba(0, 0, 0, 0.8); padding: 4px 8px;">Made with <img src="https://enzostvs-deepsite.hf.space/logo.svg" alt="DeepSite Logo" style="width: 16px; height: 16px; vertical-align: middle;display:inline-block;margin-right:3px;filter:brightness(0) invert(1);"><a href="https://enzostvs-deepsite.hf.space" style="color: #fff;text-decoration: underline;" target="_blank" >DeepSite</a> - 🧬 <a href="https://enzostvs-deepsite.hf.space?remix=bozhong/awesome-about-me" style="color: #fff;text-decoration: underline;" target="_blank" >Remix</a></p><p style="border-radius: 8px; text-align: center; font-size: 12px; color: #fff; margin-top: 16px;position: fixed; left: 8px; bottom: 8px; z-index: 10; background: rgba(0, 0, 0, 0.8); padding: 4px 8px;">Made with <img src="https://enzostvs-deepsite.hf.space/logo.svg" alt="DeepSite Logo" style="width: 16px; height: 16px; vertical-align: middle;display:inline-block;margin-right:3px;filter:brightness(0) invert(1);"><a href="https://enzostvs-deepsite.hf.space" style="color: #fff;text-decoration: underline;" target="_blank" >DeepSite</a> - 🧬 <a href="https://enzostvs-deepsite.hf.space?remix=bozhong/snake" style="color: #fff;text-decoration: underline;" target="_blank" >Remix</a></p></body> | |
| </html> |