- BC20280055's blog
贪吃蛇
- @ 2025-11-5 22:33:54
贪吃蛇游戏
body {
display: flex;
justify-content: center;
align-items: center;
height: 100vh;
margin: 0;
background-color: #B6C79C;
font-family: monospace;
overflow: hidden;
}
.game-container {
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
width: 100%;
height: 100%;
}
.title {
font-family: monospace;
font-size: 32px;
color: #3B3B3B;
font-weight: bold;
margin-bottom: 5px;
}
.score {
color: #3B3B3B;
font-size: 16px;
line-height: 1.5;
margin-bottom: 30px;
}
#gameCanvas {
width: 400px;
height: 400px;
border: 2px dashed #555555;
background-color: #B6C79C;
image-rendering: pixelated;
max-width: 100%;
}
.controls {
font-size: 14px;
line-height: 1.5;
color: #3B3B3B;
text-align: center;
margin-top: 20px;
}
* {
position: relative;
z-index: 2;
}
</style>
贪吃蛇
得分: 0
使用方向键控制移动
按空格键开始/暂停游戏
<script>
// 游戏常量
const GRID_SIZE = 16;
const CANVAS_SIZE = 400;
const GRID_COUNT = CANVAS_SIZE / GRID_SIZE;
// 游戏变量
let snake = [{x: 10, y: 10}];
let food = {x: 5, y: 5};
let direction = {x: 0, y: 0};
let nextDirection = {x: 0, y: 0};
let score = 0;
let gameStarted = false;
let gamePaused = false;
let gameSpeed = 150;
let gameLoopId;
// 获取DOM元素
const canvas = document.getElementById('gameCanvas');
const ctx = canvas.getContext('2d');
const scoreValue = document.getElementById('scoreValue');
// 初始化游戏
function initGame() {
snake = [{x: 10, y: 10}];
generateFood();
direction = {x: 0, y: 0};
nextDirection = {x: 0, y: 0};
score = 0;
scoreValue.textContent = score;
gameStarted = false;
gamePaused = false;
draw();
}
// 生成食物
function generateFood() {
// 生成随机位置
food = {
x: Math.floor(Math.random() * GRID_COUNT),
y: Math.floor(Math.random() * GRID_COUNT)
};
// 确保食物不在蛇身上
for (let segment of snake) {
if (segment.x === food.x && segment.y === food.y) {
return generateFood();
}
}
}
// 绘制游戏
function draw() {
// 清空画布
ctx.fillStyle = '#B6C79C';
ctx.fillRect(0, 0, CANVAS_SIZE, CANVAS_SIZE);
// 绘制网格线
ctx.strokeStyle = '#DCE7D4';
ctx.lineWidth = 0.25;
for (let i = 0; i <= GRID_COUNT; i++) {
// 垂直线
ctx.beginPath();
ctx.moveTo(i * GRID_SIZE, 0);
ctx.lineTo(i * GRID_SIZE, CANVAS_SIZE);
ctx.stroke();
// 水平线
ctx.beginPath();
ctx.moveTo(0, i * GRID_SIZE);
ctx.lineTo(CANVAS_SIZE, i * GRID_SIZE);
ctx.stroke();
}
// 绘制蛇
ctx.fillStyle = '#202020';
for (let segment of snake) {
ctx.fillRect(
segment.x * GRID_SIZE,
segment.y * GRID_SIZE,
GRID_SIZE,
GRID_SIZE
);
// 绘制蛇身边框
ctx.strokeStyle = '#3B3B3B';
ctx.lineWidth = 0.5;
ctx.strokeRect(
segment.x * GRID_SIZE,
segment.y * GRID_SIZE,
GRID_SIZE,
GRID_SIZE
);
}
// 绘制食物
ctx.fillStyle = '#00AA00';
ctx.fillRect(
food.x * GRID_SIZE,
food.y * GRID_SIZE,
GRID_SIZE,
GRID_SIZE
);
// 绘制食物边框
ctx.strokeStyle = '#007700';
ctx.lineWidth = 0.5;
ctx.strokeRect(
food.x * GRID_SIZE,
food.y * GRID_SIZE,
GRID_SIZE,
GRID_SIZE
);
// 绘制开始/暂停提示
if (!gameStarted) {
drawCenterText("按空格键开始游戏", "#3B3B3B", 20);
} else if (gamePaused) {
drawCenterText("游戏暂停", "#3B3B3B", 20);
}
}
// 绘制居中文字
function drawCenterText(text, color, fontSize) {
ctx.fillStyle = color;
ctx.font = `${fontSize}px Arial`;
ctx.textAlign = 'center';
ctx.textBaseline = 'middle';
ctx.fillText(text, CANVAS_SIZE / 2, CANVAS_SIZE / 2);
}
// 移动蛇
function moveSnake() {
if (!gameStarted || gamePaused) return;
// 更新方向
direction = {...nextDirection};
// 计算新蛇头位置
const head = {...snake[0]};
head.x += direction.x;
head.y += direction.y;
// 边界检测
if (
head.x < 0 ||
head.x >= GRID_COUNT ||
head.y < 0 ||
head.y >= GRID_COUNT
) {
resetGame();
return;
}
// 自身碰撞检测
for (let segment of snake) {
if (head.x === segment.x && head.y === segment.y) {
resetGame();
return;
}
}
// 添加新蛇头
snake.unshift(head);
// 检查是否吃到食物
if (head.x === food.x && head.y === food.y) {
// 增加分数
score += 10;
scoreValue.textContent = score;
// 生成新食物
generateFood();
// 增加游戏速度(最多加快到50ms)
if (gameSpeed > 50) {
gameSpeed -= 2;
}
} else {
// 移除蛇尾
snake.pop();
}
draw();
}
// 游戏循环
function gameLoop() {
moveSnake();
if (gameStarted && !gamePaused) {
gameLoopId = setTimeout(gameLoop, gameSpeed);
}
}
// 开始游戏
function startGame() {
if (!gameStarted) {
gameStarted = true;
direction = {x: 1, y: 0}; // 默认向右移动
nextDirection = {x: 1, y: 0};
gameLoop();
} else if (gamePaused) {
gamePaused = false;
gameLoop();
}
}
// 暂停游戏
function pauseGame() {
if (gameStarted && !gamePaused) {
gamePaused = true;
}
}
// 重置游戏
function resetGame() {
clearTimeout(gameLoopId);
initGame();
}
// 键盘事件监听
document.addEventListener('keydown', e => {
switch (e.key) {
case 'ArrowUp':
if (direction.y !== 1) { // 防止反向移动
nextDirection = {x: 0, y: -1};
}
break;
case 'ArrowDown':
if (direction.y !== -1) { // 防止反向移动
nextDirection = {x: 0, y: 1};
}
break;
case 'ArrowLeft':
if (direction.x !== 1) { // 防止反向移动
nextDirection = {x: -1, y: 0};
}
break;
case 'ArrowRight':
if (direction.x !== -1) { // 防止反向移动
nextDirection = {x: 1, y: 0};
}
break;
case ' ':
e.preventDefault(); // 防止空格键滚动页面
if (!gameStarted) {
startGame();
} else {
if (gamePaused) {
startGame();
} else {
pauseGame();
}
}
break;
}
});
// 初始化游戏
initGame();
</script>