打造你的贪吃蛇游戏:HTML、CSS与JavaScript的完美结合

🌟 前言

欢迎来到我的技术小宇宙!🌌 这里不仅是我记录技术点滴的后花园,也是我分享学习心得和项目经验的乐园。📚 无论你是技术小白还是资深大牛,这里总有一些内容能触动你的好奇心。🔍

在这里插入图片描述

打造你的贪吃蛇游戏:HTML、CSS与JavaScript的完美结合

摘要

在本教程中,我们将通过一个简单的贪吃蛇游戏来学习如何使用HTML、CSS和JavaScript创建一个有趣的网页游戏。我们将逐步解读代码,了解游戏的构建过程,并提供必要的注释来帮助理解每个部分的功能。

体验地址

PC端体验地址: 洛可可白⚡️贪吃蛇

(暂时只支持键盘输入操作)

在这里插入图片描述

1. 创建游戏的基本结构

首先,我们需要创建一个HTML页面,它将包含游戏的所有元素,如游戏区域、分数和等级显示。

<!DOCTYPE html>
<html lang="en">
<head>
  <!-- ... 其他头部代码 ... -->
  <title>洛可可白⚡️贪吃蛇</title>
  <style>
    /* ... 样式代码 ... */
  </style>
</head>
<body>
  <!-- ... 页面内容 ... -->
  <script>
    // ... JavaScript 代码 ...
  </script>
</body>
</html>

2. 设计游戏界面

使用CSS来设计游戏的界面,包括游戏区域的样式、蛇和食物的外观。

/* ... 样式代码 ... */
.gamBox {
  /* ... 游戏盒子样式 ... */
        width: 500px;
        height: 500px;
        border: 10px solid #393c1b;
        margin: 20px auto;
        background-color: #b6b327;
        border-radius: 20px;
        display: flex;
        flex-direction: column;
        justify-content: space-around;
        align-items: center;
}
.screen {
  /* ... 屏幕样式 ... */
        width: 400px;
        height: 400px;
        border: 1px solid #000;
        position: relative;
}
  /* ... 蛇的样式 ... */
      .snake .snake-head {
        width: 20px;
        height: 20px;
        border: 1px solid #4d7d2b;
        background-color: #000;
        position: absolute;
        top: 0;
        left: 0;
      }

      .snake span {
        font-size: 17px;
        position: absolute;
        left: -2.7px;
        top: -3px;
      }

      .snake-body > div {
        position: absolute;
        top: 0;
        left: 0;
        width: 20px;
        height: 20px;
        border: 1px solid #4d7d2b;
        background-color: #000;
      }

  /* ... 食物的样式 ... */
 .food {
        width: 20px;
        height: 20px;
        font-size: 8px;
        text-align: left;
        position: absolute;
        top: 10px;
        left: 0;
      }

      .food span {
        font-size: 17px;
        position: absolute;
        left: -1.7px;
        top: -2px;
      }

3. 初始化游戏变量

在JavaScript中,我们定义了一些变量来控制游戏的逻辑,如基础倍数、最大等级、食物位置、等级和分数。

const foundationNumber = 20;
const maxGrade = 10;
let foodSeat = { top. 20, left. 20 };
let register = { score. 0, grade. 1 };

4. 食物位置的随机化

创建一个函数来随机生成食物的位置,并在游戏开始时调用它。

const changeFoodSeat = () => {
  // ... 随机位置代码 ...
          foodSeat.top = randomNumber(0, 20) * foundationNumber;
      foodSeat.left = randomNumber(0, 20) * foundationNumber;

      document.querySelector(".food").style.cssText =
        "left:" + foodSeat.left + "px;top:" + foodSeat.top + "px";
};

5. 更新等级和分数

每当蛇吃到食物时,我们需要更新等级和分数,并在页面上显示。

const changeScore = () => {
  // ... 更新分数和等级代码 ...
          register.score++;
      if (register.grade < 10) {
        register.grade = Math.ceil(register.score / 10);
      }

      document.querySelector(".grade").innerText = register.grade;
      document.querySelector(".score").innerText = register.score;
};

6. 蛇的移动逻辑

编写蛇的移动逻辑,包括方向控制、身体部分的移动以及检测碰撞。

const handleWatchEnter = (e) => {
  // ... 蛇的移动逻辑 ...
    let previousTop = snakeSeat.top;
      let previousLeft = snakeSeat.left;
      //通过便利每个身体部分来进行移动
      snakeLength.forEach((ele, index) => {
        let temporaryTop = ele.top;
        let temporaryLeft = ele.left;
        ele.top = previousTop;
        ele.left = previousLeft;
        previousTop = temporaryTop;
        previousLeft = temporaryLeft;
        document.querySelectorAll(".snake-body>div")[index].style.cssText =
          "left:" + ele.left + "px;top:" + ele.top + "px";
};

7. 键盘事件处理

监听键盘事件来控制蛇的移动方向。

document.addEventListener("keydown", (e) => {
  // ... 键盘事件处理代码 ...
});

8. 初始化游戏

最后,我们初始化游戏,设置初始位置和分数,并开始游戏循环。

const init = () => {
  // ... 初始化游戏代码 ...
          document.querySelector(".snake-head").style.cssText =
        "left:" + 0 + "px;top:" + 0 + "px";
      document.querySelector(".snake-body").innerHTML = "";
      document.querySelector(".grade").innerText = register.grade;
      document.querySelector(".score").innerText = register.score;
      changeFoodSeat();
      handleWatchEnter();
    };

    document.addEventListener("keydown", (e) => {
      if (
        (e.code == "ArrowUp" && direction != "ArrowDown") ||
        (e.code == "ArrowLeft" && direction != "ArrowRight") ||
        (e.code == "ArrowRight" && direction != "ArrowLeft") ||
        (e.code == "ArrowDown" && direction != "ArrowUp")
      ) {
        direction = e.code;
      }
};
init();

9. 全部代码

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta http-equiv="X-UA-Compatible" content="IE=edge" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>洛可可白⚡️贪吃蛇</title>
    <style>
      * {
        margin: 0;
        padding: 0;
        box-sizing: border-box;
      }

      p {
        text-align: center;
        font-size: 23px;
        font-weight: 600;
      }

      .gamBox {
        width: 500px;
        height: 500px;
        border: 10px solid #393c1b;
        margin: 20px auto;
        background-color: #b6b327;
        border-radius: 20px;
        display: flex;
        flex-direction: column;
        justify-content: space-around;
        align-items: center;
      }

      /* //下方等级、得分盒子/ */
      .integral {
        width: 398px;
        height: 25px;
        display: flex;
        justify-content: space-between;
        font-size: 16px;
        font-family: "Trebuchet MS", "Lucida Sans Unicode", "Lucida Grande",
          "Lucida Sans", Arial, sans-serif;
        font-weight: 700;
      }

      /* //屏幕样式 */
      .screen {
        width: 400px;
        height: 400px;
        border: 1px solid #000;
        position: relative;
      }

      /* //蛇的样式 */
      .snake .snake-head {
        width: 20px;
        height: 20px;
        border: 1px solid #4d7d2b;
        background-color: #000;
        position: absolute;
        top: 0;
        left: 0;
      }

      .snake span {
        font-size: 17px;
        position: absolute;
        left: -2.7px;
        top: -3px;
      }

      .snake-body > div {
        position: absolute;
        top: 0;
        left: 0;
        width: 20px;
        height: 20px;
        border: 1px solid #4d7d2b;
        background-color: #000;
      }

      /* //食物的样式 */

      .food {
        width: 20px;
        height: 20px;
        font-size: 8px;
        text-align: left;
        position: absolute;
        top: 10px;
        left: 0;
      }

      .food span {
        font-size: 17px;
        position: absolute;
        left: -1.7px;
        top: -2px;
      }
    </style>
  </head>

  <body>
    <p>贪吃蛇</p>
    <div class="gamBox">
      <div class="screen">
        <div class="snake">
          <div class="snake-head">
            <span>😁</span>
          </div>
          <div class="snake-body"></div>
        </div>

        <div class="food">
          <span>🐷</span>
        </div>
      </div>
      <div class="integral">
        <div>等级(grade)<span class="grade"></span></div>
        <div>分数(score)<span class="score"></span></div>
      </div>
    </div>
  </body>

  <script>
    /***
     * 公用变量
     * @foundationNumber 基础倍数:移动、食物随机位置量的倍数
     * @maxGrade 最大的等级
     */

    const foundationNumber = 20;
    const maxGrade = 10;

    /***
     * 食物相关
     */
    const randomNumber = (min, max) => {
      return Math.floor(Math.random() * (max - min)) + min;
    };
    let foodSeat = {
      top: 20,
      left: 20,
    };
    const changeFoodSeat = () => {
      foodSeat.top = randomNumber(0, 20) * foundationNumber;
      foodSeat.left = randomNumber(0, 20) * foundationNumber;

      document.querySelector(".food").style.cssText =
        "left:" + foodSeat.left + "px;top:" + foodSeat.top + "px";
    };

    /***
     * 等级、分数相关
     */
    let register = {
      score: 0,
      grade: 1,
    };
    const changeScore = () => {
      register.score++;
      if (register.grade < 10) {
        register.grade = Math.ceil(register.score / 10);
      }

      document.querySelector(".grade").innerText = register.grade;
      document.querySelector(".score").innerText = register.score;
    };

    /***
     * 蛇相关
     */

    let direction = ""; //移动方向
    let snakeLength = [];
    let snakeSeat = {
      top: 0,
      left: 0,
    };
    const handleWatchEnter = (e) => {
      let previousTop = snakeSeat.top;
      let previousLeft = snakeSeat.left;
      //通过便利每个身体部分来进行移动
      snakeLength.forEach((ele, index) => {
        let temporaryTop = ele.top;
        let temporaryLeft = ele.left;
        ele.top = previousTop;
        ele.left = previousLeft;
        previousTop = temporaryTop;
        previousLeft = temporaryLeft;
        document.querySelectorAll(".snake-body>div")[index].style.cssText =
          "left:" + ele.left + "px;top:" + ele.top + "px";
      });

      switch (direction) {
        case "ArrowUp":
          snakeSeat.top -= 20;
          break;
        case "ArrowLeft":
          snakeSeat.left -= 20;
          break;
        case "ArrowRight":
          snakeSeat.left += 20;
          break;
        case "ArrowDown":
          snakeSeat.top += 20;
          break;
      }

      if (snakeSeat.top == foodSeat.top && snakeSeat.left == foodSeat.left) {
        changeScore();
        changeFoodSeat();
        snakeLength.push({
          top: previousTop,
          left: previousLeft,
        });

        var div = document.createElement("div");
        div.style.left = previousLeft + "px";
        div.style.top = previousTop + "px";
        div.class = "bodyItem";

        document.querySelector(".snake-body").appendChild(div);
      }

      if (
        snakeSeat.top < 0 ||
        snakeSeat.left < 0 ||
        snakeSeat.left > 380 ||
        snakeSeat.top > 380
      ) {
        alert("撞墙身亡");
        snakeSeat.top = 0;
        snakeSeat.left = 0;
        direction = "";
        snakeLength = [];
        init();

        return;
      }

      let bodySeats = snakeLength.map((item) => JSON.stringify(item));

      if (
        bodySeats.indexOf(
          JSON.stringify({ top: snakeSeat.top, left: snakeSeat.left })
        ) != -1
      ) {
        alert("把自己撞死了");
        snakeSeat.top = 0;
        snakeSeat.left = 0;
        snakeLength = [];
        direction = "";
        init();
        return;
      }
      document.querySelector(".snake-head").style.cssText =
        "left:" + snakeSeat.left + "px;top:" + snakeSeat.top + "px";
      setTimeout(() => {
        handleWatchEnter();
      }, 400 - (register.grade - 1) * 15);
    };

    //函数节流
    const throttle = (fn, wait) => {
      var timer = null;
      return function () {
        var _this = this;
        var args = arguments;
        if (!timer) {
          timer = setTimeout(function () {
            fn.apply(_this, args);
            timer = null;
          }, wait);
        }
      };
    };

    const init = () => {
      document.querySelector(".snake-head").style.cssText =
        "left:" + 0 + "px;top:" + 0 + "px";
      document.querySelector(".snake-body").innerHTML = "";
      document.querySelector(".grade").innerText = register.grade;
      document.querySelector(".score").innerText = register.score;
      changeFoodSeat();
      handleWatchEnter();
    };

    document.addEventListener("keydown", (e) => {
      if (
        (e.code == "ArrowUp" && direction != "ArrowDown") ||
        (e.code == "ArrowLeft" && direction != "ArrowRight") ||
        (e.code == "ArrowRight" && direction != "ArrowLeft") ||
        (e.code == "ArrowDown" && direction != "ArrowUp")
      ) {
        direction = e.code;
      }
    });
    init();
  </script>
</html>

结论

通过本教程,我们学习了如何使用HTML、CSS和JavaScript创建一个简单的贪吃蛇游戏。这个过程不仅涉及到前端开发的基础知识,还包括了游戏逻辑的设计。现在,你可以根据自己的需求扩展和优化这个游戏,或者尝试创建其他类型的网页游戏。祝你编程愉快!

感谢你的访问,期待与你在技术的道路上相遇!👋🌟🚀

  • 27
    点赞
  • 14
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

洛可可白

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值