本帖最后由 xuexi2026 于 2026-9-15 21:51 编辑
[XHTML] 纯文本查看 复制代码 <!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8">
<title>10关贪吃蛇</title>
<style>
* {margin:0;padding:0;box-sizing:border-box;font-family:system-ui;}
body {background:#1a1a1a;color:#fff;display:flex;flex-direction:column;align-items:center;padding:20px;}
#gameBox {border:3px solid #4cd964;background:#000;}
.info {margin-bottom:10px;font-size:18px;}
.tip {margin-top:10px;color:#aaa;text-align:center;}
button {padding:8px 16px;margin:5px;font-size:16px;cursor:pointer;background:#4cd964;border:none;border-radius:4px;color:#000;font-weight:bold;}
</style>
</head>
<body>
<div class="info">
关卡:<span id="level">1</span> / 10 | 得分:<span id="score">0</span> | 本关目标:<span id="target">5</span>分
</div>
<canvas id="gameBox" width="400" height="400"></canvas>
<div class="tip">方向键 ↑ ↓ ← → 控制蛇,吃到食物加分,撞墙/撞自己游戏结束</div>
<button id="restartBtn">重新开始</button>
<script>
const canvas = document.getElementById('gameBox');
const ctx = canvas.getContext('2d');
const levelText = document.getElementById('level');
const scoreText = document.getElementById('score');
const targetText = document.getElementById('target');
const restartBtn = document.getElementById('restartBtn');
const size = 20;
const count = canvas.width / size;
// 10关配置:[每关需要吃的食物数量, 速度(ms)]
const levelConfig = [
{target:5, speed:180},
{target:8, speed:160},
{target:10, speed:140},
{target:12, speed:120},
{target:15, speed:100},
{target:18, speed:90},
{target:20, speed:80},
{target:22, speed:70},
{target:25, speed:60},
{target:30, speed:50},
];
let level = 0;
let score = 0;
let snake = [];
let dx = size, dy = 0;
let food = {};
let timer = null;
let gameOver = false;
let passAll = false;
// 初始化游戏
function initGame(){
level = 0;
score = 0;
gameOver = false;
passAll = false;
startLevel();
}
// 开启当前关卡
function startLevel(){
clearInterval(timer);
const cfg = levelConfig[level];
levelText.innerText = level+1;
targetText.innerText = cfg.target;
scoreText.innerText = score;
snake = [{x: size*5, y: size*5}];
dx = size; dy = 0;
createFood();
gameOver = false;
timer = setInterval(gameLoop, cfg.speed);
}
// 生成食物
function createFood(){
let newFood;
while(true){
newFood = {
x: Math.floor(Math.random()*count)*size,
y: Math.floor(Math.random()*count)*size
}
// 食物不能出现在蛇身上
const overlap = snake.some(seg=>seg.x===newFood.x && seg.y===newFood.y);
if(!overlap) break;
}
food = newFood;
}
// 游戏循环
function gameLoop(){
if(gameOver) return;
// 蛇头新位置
const head = {x: snake[0].x + dx, y: snake[0].y + dy};
// 撞墙判断
if(head.x <0 || head.y <0 || head.x >= canvas.width || head.y >= canvas.height){
gameOver = true;
clearInterval(timer);
alert(`第${level+1}关失败!撞墙了,点击重新开始`);
return;
}
// 撞到自己
if(snake.some(seg=>seg.x===head.x && seg.y===head.y)){
gameOver = true;
clearInterval(timer);
alert(`第${level+1}关失败!咬到自己了,点击重新开始`);
return;
}
snake.unshift(head);
// 吃到食物
if(head.x === food.x && head.y === food.y){
score++;
scoreText.innerText = score;
createFood();
// 判断本关通关
if(score >= levelConfig[level].target){
level++;
// 判断是否全部通关
if(level >= levelConfig.length){
clearInterval(timer);
passAll = true;
alert("🎉恭喜!通关全部10关!");
return;
}else{
alert(`✅第${level}关通关!即将进入第${level+1}关`);
startLevel();
return;
}
}
}else{
snake.pop();
}
draw();
}
// 绘制画面
function draw(){
ctx.fillStyle="#000";
ctx.fillRect(0,0,canvas.width,canvas.height);
// 蛇
ctx.fillStyle="#4cd964";
snake.forEach(seg=>{
ctx.fillRect(seg.x, seg.y, size-2, size-2);
})
// 食物
ctx.fillStyle="#ff3b30";
ctx.fillRect(food.x, food.y, size-2, size-2);
}
// 键盘控制方向
document.addEventListener('keydown',e=>{
if(gameOver) return;
switch(e.key){
case 'ArrowUp': if(dy!==size){dx=0;dy=-size;}break;
case 'ArrowDown': if(dy!==-size){dx=0;dy=size;}break;
case 'ArrowLeft': if(dx!==size){dx=-size;dy=0;}break;
case 'ArrowRight': if(dx!==-size){dx=size;dy=0;}break;
}
})
restartBtn.onclick = initGame;
initGame();
</script>
</body>
</html>
直接复制保存为 snake.html,用浏览器打开即可游玩。 |