马上注册,结交更多好友,享用更多功能^_^
您需要 登录 才可以下载或查看,没有账号?立即注册
x
本帖最后由 中英文泡椒 于 2025-2-10 19:12 编辑
贪吃蛇大家都玩过,新春版贪吃蛇大家体验过吗
项目介绍
传统贪吃蛇游戏玩家通过控制蛇的移动方向来吃食物,食物越多,蛇的长度越长。
游戏的目标是尽可能获得更高的分数,而我们的新春版贪吃蛇,
通过调用 placeFood 方法,生成随机位置的食物并从 fishc 字符串中取出一个汉字作为食物的字符。
每次蛇吃到食物时,从这个字符串中取出一个汉字并显示在蛇的身体上。
这不仅是一款经典的贪吃蛇游戏,还能通过在一步步吃的过程中,把祝福吃下去,
寓意“贪吃蛇”逐渐吞噬好运,寓意“越吃越有福气”。
完整代码
<!DOCTYPE html>
<html lang="zh">
<head>
<meta charset="UTF-8" />
<title>贪吃蛇</title>
<style>
body {
text-align: center;
margin-top: 50px;
font-family: Arial, sans-serif;
}
#gameCanvas {
border: 2px solid #333;
background-color: #fafafa;
display: block;
margin: 0 auto;
}
#score {
font-size: 1.2em;
margin-bottom: 10px;
}
</style>
</head>
<body>
<h1>贪吃蛇</h1>
<div id="score">得分:<span id="scoreValue">0</span></div>
<canvas id="gameCanvas" width="400" height="400"></canvas>
<script>
// 1. 获取画布和上下文
const canvas = document.getElementById('gameCanvas');
const ctx = canvas.getContext('2d');
const scoreValue = document.getElementById('scoreValue');
// 2. 基本参数
const gridSize = 20; // 每格像素
const tileCount = canvas.width / gridSize;
let score = 0;
let gameOver = false;
// 3. 包含汉字的字符串
const fishc = "恭贺新春大吉大利蛇年发大财";
let fishcIndex = 0; // 用于依次取汉字
// 4. 蛇的初始状态(数组第0项是蛇头)
// 蛇的每个身体段仅存坐标 (x, y),不存汉字
// 汉字将统一保存在 eatenChars 里,按吃到的先后顺序排列
let snake = [
{ x: 10, y: 10 } // 仅有一个头部,坐标可自行调整
];
// 5. 用于存储“吃到的汉字”的数组
// eatenChars[0] 表示最早吃到的汉字,eatenChars[1] 表示第二次吃到的汉字...
let eatenChars = [];
// 6. 食物对象(带有汉字)
let food = { x: 0, y: 0, char: '' };
// 7. 初始方向:向右(dx=1, dy=0)
let dx = 1;
let dy = 0;
// 8. 放置食物 + 取汉字
function placeFood() {
food.x = Math.floor(Math.random() * tileCount);
food.y = Math.floor(Math.random() * tileCount);
food.char = fishc[fishcIndex];
fishcIndex = (fishcIndex + 1) % fishc.length; // 循环取
}
placeFood(); // 游戏开始先放一次食物
// 9. 游戏主循环
function gameLoop() {
if (gameOver) return;
update();
draw();
}
// 10. 更新
function update() {
// 先计算新头部坐标
const newHead = {
x: snake[0].x + dx,
y: snake[0].y + dy
};
// (1) 撞墙检测
if (newHead.x < 0 || newHead.x >= tileCount ||
newHead.y < 0 || newHead.y >= tileCount) {
endGame();
return;
}
// (2) 撞到自己
for (let i = 0; i < snake.length; i++) {
if (snake[i].x === newHead.x && snake[i].y === newHead.y) {
endGame();
return;
}
}
// (3) 在头部插入新头
snake.unshift(newHead);
// (4) 判断是否吃到食物
if (newHead.x === food.x && newHead.y === food.y) {
// 吃到后分数加1,且“蛇长度+1”(本回合不 pop)
score++;
scoreValue.textContent = score;
// 将本次食物的汉字加入到 eatenChars 的“队尾”
// 表示这是最新吃到的汉字
eatenChars.push(food.char);
// 生成下一个食物
placeFood();
} else {
// 没吃到,就移除尾巴(保持长度不变)
snake.pop();
}
}
// 11. 结束游戏
function endGame() {
gameOver = true;
alert(`游戏结束!得分:${score}`);
}
// 12. 绘制
function draw() {
// 清空画布
ctx.clearRect(0, 0, canvas.width, canvas.height);
// 设置绘制文字属性
ctx.font = "16px sans-serif";
ctx.textBaseline = "top";
// (A) 先画蛇
// snake[0] 是头部,不显示汉字
// snake[1] ~ snake[n-1] 依次显示 eatenChars[0] ~ eatenChars[n-2]
// 即:第一个吃到的汉字放在蛇的第1节位置,第二个吃到的放第2节位置……
for (let i = 0; i < snake.length; i++) {
// 画身体方块
ctx.fillStyle = "#008000"; // 绿色
ctx.fillRect(
snake[i].x * gridSize,
snake[i].y * gridSize,
gridSize,
gridSize
);
// 从第1节开始,若存在对应的 eatenChars[i-1] 则显示
if (i > 0) {
// i-1 对应 eatenChars 的下标
let charIndex = i - 1;
if (charIndex < eatenChars.length) {
ctx.fillStyle = "#FFFFFF"; // 白色文字
ctx.fillText(
eatenChars[charIndex],
snake[i].x * gridSize + 2,
snake[i].y * gridSize + 2
);
}
}
}
// (B) 再画食物:红底黑字
ctx.fillStyle = "#FF0000";
ctx.fillRect(food.x * gridSize, food.y * gridSize, gridSize, gridSize);
ctx.fillStyle = "#000000";
ctx.fillText(
food.char,
food.x * gridSize + 2,
food.y * gridSize + 2
);
}
// 13. 方向键控制
document.addEventListener('keydown', function (e) {
switch (e.key) {
case 'ArrowLeft':
if (dx !== 1) {
dx = -1;
dy = 0;
}
break;
case 'ArrowUp':
if (dy !== 1) {
dx = 0;
dy = -1;
}
break;
case 'ArrowRight':
if (dx !== -1) {
dx = 1;
dy = 0;
}
break;
case 'ArrowDown':
if (dy !== -1) {
dx = 0;
dy = 1;
}
break;
}
});
// 14. 启动游戏循环
setInterval(gameLoop, 120);
</script>
</body>
</html>
大家有改进的建议可以评论一下,求评分
@cjjJasonchen @yinda_peng @python爱好者. @鱼小二 @学习编程中的Ben @唯有无奈 @sfqxx @小凯2013 @KeyError @元豪
|