使用JS开发贪吃蛇游戏,含完整代码

今天我们来一起用JavaScript做一个贪吃蛇小游戏。就像养一条永远吃不饱的小蛇,我们要用键盘操控它满地图找"披萨"吃!准备好了吗?让我们开始吧~ 🐍🍕


第一章:搭建游戏舞台(HTML+CSS)

<!DOCTYPE html>
<html>
  <head>
    <title>贪吃蛇大冒险</title>
    <style>
      body {
        margin: 0;
        padding: 0;
        background: #ecf0f1;
      }

      .header {
        display: flex;
        justify-content: space-between;
        align-items: center;
        padding: 10px;
        background: #34495e;
        color: #ecf0f1;
      }

      #score {
        font-size: 18px;
      }

      #restart {
        font-size: 18px;
        cursor: pointer;
      }
      /* 游戏舞台 */
      #game-board {
        position: relative;
        margin: 0 auto;
        background: #2c3e50; /* 深蓝背景像夜空 */
        border: 3px solid #ecf0f1; /* 白色边框 */
      }

      /* 贪吃蛇的皮肤 */
      .snake {
        background: #2ecc71; /* 青绿色蛇身 */
        border: 1px solid #27ae60; /* 深绿边框 */
      }

      /* 蛇头的特别装扮 */
      .snake-head {
        background: #e74c3c !important; /* 红色蛇头 */
      }

      /* 食物看起来像小披萨 */
      .food {
        background: #f1c40f; /* 金黄色 */
        border-radius: 50%; /* 圆形 */
      }
    </style>
  </head>
  <body>
    <div class="header">
      <div id="score">得分:0</div>
      <div id="restart">重新开始</div>
    </div>
    <div id="game-board"></div>
  </body>
</html>

这里我们创建了:

  1. 一个显示得分的区域
  2. 游戏画布(用CSS绘制背景和边框)
  3. 定义了蛇和食物的样式,用颜色区分

第二章:召唤贪吃蛇(JavaScript核心代码)

<script>
      class SnakeGame {
        constructor() {
          this.boardSize = 20; // 20x20的网格
          this.cellSize = 20; // 每个格子20像素
          this.snake = [[10, 10]]; // 初始位置
          this.direction = "right"; // 初始方向
          this.food = this.generateFood();
          this.score = 0;

          // 创建游戏地图
          this.board = document.getElementById("game-board");
          this.board.style.width = this.boardSize * this.cellSize + "px";
          this.board.style.height = this.boardSize * this.cellSize + "px";

          // 绘制初始地图
          this.draw();

          // 开始游戏循环
          this.gameLoop = setInterval(() => this.move(), 150);

          // 监听键盘事件
          document.addEventListener("keydown", (e) => this.handleKeyPress(e));
        }

        // 绘制整个地图
        draw() {
          this.board.innerHTML = ""; // 清空画布

          // 绘制蛇
          this.snake.forEach((segment, index) => {
            const cell = document.createElement("div");
            cell.style.width = this.cellSize + "px";
            cell.style.height = this.cellSize + "px";
            cell.style.position = "absolute";
            cell.style.left = segment[0] * this.cellSize + "px";
            cell.style.top = segment[1] * this.cellSize + "px";
            cell.className = "snake" + (index === 0 ? " snake-head" : "");
            this.board.appendChild(cell);
          });

          // 绘制食物
          const foodCell = document.createElement("div");
          foodCell.style.width = this.cellSize + "px";
          foodCell.style.height = this.cellSize + "px";
          foodCell.style.position = "absolute";
          foodCell.style.left = this.food[0] * this.cellSize + "px";
          foodCell.style.top = this.food[1] * this.cellSize + "px";
          foodCell.className = "food";
          this.board.appendChild(foodCell);
        }

        // 生成随机食物
        generateFood() {
          while (true) {
            const x = Math.floor(Math.random() * this.boardSize);
            const y = Math.floor(Math.random() * this.boardSize);
            // 确保食物不在蛇身上
            if (
              !this.snake.some(
                (segment) => segment[0] === x && segment[1] === y
              )
            ) {
              return [x, y];
            }
          }
        }

        // 处理键盘事件
        handleKeyPress(e) {
          const keyMap = {
            ArrowUp: "up",
            ArrowDown: "down",
            ArrowLeft: "left",
            ArrowRight: "right",
          };
          const newDir = keyMap[e.key];
          // 禁止反向移动(比如不能从右直接转左)
          if (
            newDir &&
            !(
              (this.direction === "up" && newDir === "down") ||
              (this.direction === "down" && newDir === "up") ||
              (this.direction === "left" && newDir === "right") ||
              (this.direction === "right" && newDir === "left")
            )
          ) {
            this.direction = newDir;
          }
        }

        // 蛇的移动逻辑
        move() {
          const head = [...this.snake[0]];

          // 计算新头部位置
          switch (this.direction) {
            case "up":
              head[1]--;
              break;
            case "down":
              head[1]++;
              break;
            case "left":
              head[0]--;
              break;
            case "right":
              head[0]++;
              break;
          }

          // 碰撞检测
          if (
            head[0] < 0 ||
            head[0] >= this.boardSize || // 撞墙
            head[1] < 0 ||
            head[1] >= this.boardSize ||
            this.snake.some(
              (segment) => segment[0] === head[0] && segment[1] === head[1]
            ) // 撞自己
          ) {
            clearInterval(this.gameLoop);
            alert("游戏结束!得分:" + this.score);
            return;
          }

          // 吃食物逻辑
          if (head[0] === this.food[0] && head[1] === this.food[1]) {
            this.score += 10;
            document.getElementById("score").textContent =
              "得分:" + this.score;
            this.food = this.generateFood();
          } else {
            this.snake.pop(); // 没吃到食物就去尾
          }

          this.snake.unshift(head); // 添加新头部
          this.draw();
        }
      }

      document.getElementById("restart").addEventListener("click", () => {
        document.getElementById("game-board").innerHTML = ""; // 清空游戏板
        document.getElementById("score").textContent = "得分:0"; // 重置得分
        new SnakeGame(); // 重新开始游戏
      });

      // 等待页面加载完成后再启动游戏
      window.addEventListener("load", (
        new SnakeGame()
      ));
    </script>

第三章:代码核心原理解析

1. 贪吃蛇的骨架(数据结构)
  • 用二维数组snake存储身体坐标,如[[10,10], [9,10], [8,10]]
  • 蛇头总是数组的第一个元素
  • 移动时在头部添加新坐标,尾部删除(除非吃到食物)
2. 移动的魔法(move方法)
  • 像传送带一样工作:每次移动时:
    1. 复制蛇头坐标
    2. 根据方向修改坐标
    3. 检查是否撞墙/撞自己
    4. 吃到食物就长身体,否则保持长度
    5. 把新头部插入数组开头
3. 食物的诞生(generateFood方法)
  • 使用while循环确保食物不会出现在蛇身上
  • 随机生成坐标直到找到合法位置
4. 控制蛇的秘籍(handleKeyPress)
  • 使用键盘事件监听方向键
  • 禁止180度急转弯(比如不能从右直接转左)
5. 视觉呈现(draw方法)
  • 通过动态创建div元素实现
  • 蛇头用特殊样式(红色)
  • 每次重绘前清空画布

第四章:如何让你的蛇更酷?

试试这些升级方案:

  1. 速度升级:每吃5个食物加快游戏速度
if(this.score % 50 === 0 && this.score > 0) {
    clearInterval(this.gameLoop);
    this.gameLoop = setInterval(() => this.move(), 150 - Math.floor(this.score/50)*10);
}
  1. 特殊食物:随机生成加速/减速食物
  2. 皮肤系统:让玩家选择不同颜色的蛇
  3. 关卡系统:增加障碍物

第五章:启动你的贪吃蛇!

把以上所有代码保存为.html文件,用浏览器打开就能玩啦!用方向键控制你的小蛇,看看你能得多少分~ 🚀

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值