中英文泡椒 发表于 2025-2-7 19:13:21

新春版贪吃蛇大冒险!祝你蛇年大吉!

本帖最后由 中英文泡椒 于 2025-2-26 18:32 编辑

贪吃蛇大家都玩过,新春版贪吃蛇大家体验过吗{:10_256:}

项目介绍



传统贪吃蛇游戏玩家通过控制蛇的移动方向来吃食物,食物越多,蛇的长度越长。

游戏的目标是尽可能获得更高的分数,而我们的新春版贪吃蛇,

通过调用 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 表示最早吃到的汉字,eatenChars 表示第二次吃到的汉字...
      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 + 1) % fishc.length; // 循环取
      }
      placeFood(); // 游戏开始先放一次食物

      // 9. 游戏主循环
      function gameLoop() {
            if (gameOver) return;
            update();
            draw();
      }

      // 10. 更新
      function update() {
            // 先计算新头部坐标
            const newHead = {
                x: snake.x + dx,
                y: snake.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.x === newHead.x && snake.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 是头部,不显示汉字
            //   snake ~ snake 依次显示 eatenChars ~ eatenChars
            //   即:第一个吃到的汉字放在蛇的第1节位置,第二个吃到的放第2节位置……
            for (let i = 0; i < snake.length; i++) {
                // 画身体方块
                ctx.fillStyle = "#008000"; // 绿色
                ctx.fillRect(
                  snake.x * gridSize,
                  snake.y * gridSize,
                  gridSize,
                  gridSize
                );

                // 从第1节开始,若存在对应的 eatenChars 则显示
                if (i > 0) {
                  // i-1 对应 eatenChars 的下标
                  let charIndex = i - 1;
                  if (charIndex < eatenChars.length) {
                        ctx.fillStyle = "#FFFFFF"; // 白色文字
                        ctx.fillText(
                            eatenChars,
                            snake.x * gridSize + 2,
                            snake.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>

大家有改进的建议可以评论一下,求评分{:10_297:}



@cjjJasonchen @yinda_peng @python爱好者. @鱼小二 @学习编程中的Ben @唯有无奈 @sfqxx @小凯2013 @KeyError @元豪

小甲鱼的二师兄 发表于 2025-2-10 19:12:28

这个不错!顶上去!!

鱼小二 发表于 2025-2-12 00:10:23

寓意“贪吃蛇”逐渐吞噬好运,寓意“越吃越有福气”。

应该改为“积攒”好运{:10_267:}

trinityee 发表于 2025-2-12 09:03:07

这个不错!顶上去!!

中英文泡椒 发表于 2025-2-12 09:23:58

鱼小二 发表于 2025-2-12 00:10
应该改为“积攒”好运

{:10_256:}好的

smallwh 发表于 2025-2-13 11:27:45

挺有意思的,顶一下

希儿的 发表于 2025-2-16 21:35:58

好欸

鱼小二 发表于 2025-2-17 19:28:57

中英文泡椒 发表于 2025-2-12 09:23
好的

还没改,快点改{:10_295:}

sfqxx 发表于 6 天前

{:10_257:}支持
页: [1]
查看完整版本: 新春版贪吃蛇大冒险!祝你蛇年大吉!