<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>贪吃蛇游戏</title>
<style>
body {
display: flex;
justify-content: center;
align-items: center;
height: 100vh;
margin: 0;
background-color: #333;
}
canvas {
border: 1px solid #fff;
}
</style>
</head>
<body>
<canvas id="gameCanvas" width="400" height="400"></canvas>
<script>
const canvas = document.getElementById('gameCanvas');
const ctx = canvas.getContext('2d');
// 常量
const GRID_SIZE = 20;
const CELL_SIZE = canvas.width / GRID_SIZE;
// 加载图片
const headImg = new Image();
const bodyImg = new Image();
const tailImg = new Image();
const foodImg = new Image();
headImg.src = 'img/head.png';
bodyImg.src = 'img/body.png';
tailImg.src = 'img/tail.png';
foodImg.src = 'img/food.png';
// 蛇的初始化
let snake = [
{ x: 5, y: 10 },
{ x: 4, y: 10 },
{ x: 3, y: 10 }
];
// 食物的初始化
let food = {
x: Math.floor(Math.random() * GRID_SIZE),
y: Math.floor(Math.random() * GRID_SIZE)
};
let direction = 'right';
let score = 0;
let gameInterval;
let gameSpeed = 300;
// 移动蛇
function moveSnake() {
const head = { x: snake[0].x, y: snake[0].y };
switch (direction) {
case 'up':
head.y--;
break;
case 'down':
head.y++;
break;
case 'left':
head.x--;
break;
case 'right':
head.x++;
break;
}
// 检查是否吃到食物
if (head.x === food.x && head.y === food.y) {
score++;
generateFood();
increaseGameSpeed();
} else {
snake.pop();
}
snake.unshift(head);
// 检查是否撞到墙壁或自己
if (head.x < 0 || head.x >= GRID_SIZE || head.y < 0 || head.y >= GRID_SIZE || checkCollision(head)) {
stopGame();
alert(`游戏结束! 你的得分是 ${score}`);
resetGame();
}
}
// 检查蛇头是否撞到自己
function checkCollision(head) {
for (let i = 1; i < snake.length; i++) {
if (head.x === snake[i].x && head.y === snake[i].y) {
return true;
}
}
return false;
}
// 绘制蛇
function drawSnake() {
ctx.clearRect(0, 0, canvas.width, canvas.height);
drawGrid();
snake.forEach((segment, index) => {
let img;
if (index === 0) {
img = headImg;
} else if (index === snake.length - 1) {
img = tailImg;
} else {
img = bodyImg;
}
ctx.save();
ctx.translate(segment.x * CELL_SIZE + CELL_SIZE / 2, segment.y * CELL_SIZE + CELL_SIZE / 2);
// 根据蛇的方向旋转图片
if (index === 0) {
switch (direction) {
case 'up':
ctx.rotate(-Math.PI / 2);
break;
case 'down':
ctx.rotate(Math.PI / 2);
break;
case 'left':
ctx.rotate(Math.PI);
break;
case 'right':
// 默认方向,不需要旋转
break;
}
}
ctx.drawImage(img, -CELL_SIZE / 2, -CELL_SIZE / 2, CELL_SIZE, CELL_SIZE);
ctx.restore();
});
drawFood();
}
// 绘制食物
function drawFood() {
ctx.drawImage(foodImg, food.x * CELL_SIZE, food.y * CELL_SIZE, CELL_SIZE, CELL_SIZE);
}
// 绘制网格
function drawGrid() {
ctx.strokeStyle = '#444';
for (let x = 0; x <= canvas.width; x += CELL_SIZE) {
ctx.beginPath();
ctx.moveTo(x, 0);
ctx.lineTo(x, canvas.height);
ctx.stroke();
}
for (let y = 0; y <= canvas.height; y += CELL_SIZE) {
ctx.beginPath();
ctx.moveTo(0, y);
ctx.lineTo(canvas.width, y);
ctx.stroke();
}
}
// 生成新的食物
function generateFood() {
food = {
x: Math.floor(Math.random() * GRID_SIZE),
y: Math.floor(Math.random() * GRID_SIZE)
};
}
// 增加游戏速度
function increaseGameSpeed() {
gameSpeed = Math.max(gameSpeed - 20, 100);
stopGame();
startGame();
}
// 重置游戏
function resetGame() {
snake = [
{ x: 5, y: 10 },
{ x: 4, y: 10 },
{ x: 3, y: 10 }
];
direction = 'right';
score = 0;
gameSpeed = 300;
generateFood();
startGame();
}
// 开始游戏
function startGame() {
gameInterval = setInterval(function() {
moveSnake();
drawSnake();
}, gameSpeed);
}
// 停止游戏
function stopGame() {
clearInterval(gameInterval);
}
// 监听键盘事件改变蛇的移动方向
document.addEventListener('keydown', (event) => {
switch (event.key) {
case 'ArrowUp':
if (direction !== 'down') direction = 'up';
break;
case 'ArrowDown':
if (direction !== 'up') direction = 'down';
break;
case 'ArrowLeft':
if (direction !== 'right') direction = 'left';
break;
case 'ArrowRight':
if (direction !== 'left') direction = 'right';
break;
}
});
// 等待图片加载完成后开始游戏
Promise.all([
new Promise(resolve => headImg.onload = resolve),
new Promise(resolve => bodyImg.onload = resolve),
new Promise(resolve => tailImg.onload = resolve),
new Promise(resolve => foodImg.onload = resolve)
]).then(() => {
resetGame();
});
</script>
</body>
</html>
大白百宝阁
- 粉丝: 146
- 资源: 2
最新资源
- MMC,模块化多电平变器,多电平变器,MMC,MMC型储能变器,MMC型SVG,statcom,静止无功发生器,APF,储能,整
- 从同课异构角度看乡村初中英语课堂中学习活动观的实践-李梦晓
- JAVA源码Java开发的SHELLCRaSH
- JAVA源码Java加密包JasyptJAVA源码Java加密包Jasypt
- 同课异构,呈现精彩课堂-以“认识平行线”教学为例胡梦文 同课异构应用于《认识平行线》教学实践探索
- JAVA源码Java和DLL(COM)互操作Jawin
- 松下FP-XH的的双PLC的10轴程序,表格定位 用于摆盘的 ,平稳运行一年,PC-LINK通信,程序分输出与调试,报警与通信
- JAVA源码Java多播通讯框架JGroups
- JAVA源码Java单点登录系统JA-SIGCAS
- JAVA源码Java常用工具包JoddJAVA源码Java常用工具包Jodd
资源上传下载、课程学习等过程中有任何疑问或建议,欢迎提出宝贵意见哦~我们会及时处理!
点击此处反馈