js实现贪吃蛇

本文展示了如何使用JavaScript实现一个基于面向对象编程的贪吃蛇游戏。首先,封装了食物对象,随机生成在游戏区域内的位置;接着,封装了蛇对象,包含蛇头和身体,并实现了蛇的移动和碰撞检测;然后,封装了游戏对象,整合食物和蛇,并添加了游戏开始、计分和结束条件;最后,提供了HTML文件用于展示游戏界面。整个实现过程详细展示了JavaScript在游戏开发中的应用。
摘要由CSDN通过智能技术生成


前言

面向对象实现贪吃蛇


1.封装食物对象

代码如下(示例):

(function (window) {
  "use strict"
  function Food(options) {
    options = options || {}
    this.width = options.width || 20;
    this.height = options.height || 20;
    this.bgc = options.bgc || "#409eff";
    this.x = options.x || 0;
    this.y = options.y || 0;
  }
  Food.prototype = {
    render: function (target) {
      const foodDiv = document.createElement("div");
      foodDiv.style.width = this.width + 'px';
      foodDiv.style.height = this.height + 'px';
      foodDiv.style.background = this.bgc;
      this.x = parseInt(Math.random() * (target.offsetWidth / this.width));//offsetWidth 元素真实的宽度
      this.y = parseInt(Math.random() * (target.offsetHeight / this.height));
      foodDiv.style.position = 'absolute';
      foodDiv.style.left = this.x * this.width + 'px';
      foodDiv.style.top = this.y * this.height + 'px';
      target.appendChild(foodDiv);//appendChild 添加结点到父元素的最后面
    }
  }
  window.Food = Food;
})(window)

2.封装蛇对象

代码如下(示例):

(function (window) {
  "use strict"
  function Snake(options) {
    options = options || {};
    this.width = options.width || 20;
    this.height = options.height || 20;
    this.headBgc = options.headBgc || "mediumturquoise";
    this.bodyBgc = options.bodyBgc || "lightgreen";
    this.direction = options.direction || "right";
    this.body = options.body || [
      { x: 2, y: 0 },
      { x: 1, y: 0 },
      { x: 0, y: 0 }
    ]
  }
  Snake.prototype = {
    render: function (target) {
      for (var i = 0; i < this.body.length; i++) {
        var span = document.createElement("span");
        span.style.width = this.width + 'px';
        span.style.height = this.height + 'px';
        if (i === 0) {
          span.style.background = this.headBgc;
        } else {
          span.style.background = this.bodyBgc;
        }
        span.style.position = 'absolute';
        span.style.left = this.width * this.body[i].x + 'px';
        span.style.top = this.height * this.body[i].y + 'px';
        target.appendChild(span);
      }
    },
    // 蛇移动 复制蛇头,删除蛇尾
    move: function (target, food, grade) {
      const newHead = {
        x: this.body[0].x,
        y: this.body[0].y
      }
      this.body.unshift(newHead);
      switch (this.direction) {
        case "top":
          newHead.y--;
          break;
        case "right":
          newHead.x++;
          break;
        case "bottom":
          newHead.y++;
          break;
        case "left":
          newHead.x--;
          break;
        default:
          break;
      }
      /** 判断蛇有没有吃到食物
      * head的坐标是否与食物的坐标相等
      * 若吃到食物,则不删除身体最后一节
      **/
      var head = this.body[0];

      if (head.x === food.x && head.y === food.y) {
        // 计分 
        grade += 10;
        const scoreSpan = document.querySelector("#score");
        scoreSpan.innerHTML = grade;

        var div = target.querySelector("div");
        target.removeChild(div);
        food.render(target);

      } else {
        this.body.pop();

      }
      // 删除地图上已有的蛇,然后再重新渲染
      const spans = target.querySelectorAll("span")//querySelectorAll()获取到的是一个伪数组
      for (let i = 0; i < spans.length; i++) {
        target.removeChild(spans[i]);//removeChild 一次只能删除一个标签
      }
      this.render(target);
      return grade;
    }
  }
  window.Snake = Snake;
})(window)

3.封装游戏对象

代码如下(示例):

(function (window) {
  "use strict"
  function Game(target) {
    this.food = new Food();
    this.snake = new Snake();
    this.map = target;
    this.score = 0;
  }
  Game.prototype = {
    render: function () {
      this.food.render(this.map);
      this.snake.render(this.map);
      const scoreSpan = document.querySelector("#score");
      scoreSpan.innerHTML = this.score;
    },
    startGame: function () {
      var that = this;
      var timeId = setInterval(function () {

        // 定时器中的this指向document
        that.score = that.snake.move(that.map, that.food, that.score);
        // 判断蛇头是否撞墙
        const head = that.snake.body[0];
        if (head.x < 0 ||
          head.x >= that.map.offsetWidth / that.snake.width ||
          head.y < 0 ||
          head.y >= that.map.offsetHeight / that.snake.height
        ) {
          alert("Game Over");
          clearInterval(timeId);
        }
        /**判断蛇是否吃到自己
         * 遍历蛇头与自己身体的坐标是否重合
         */
        for (let i = 4; i < that.snake.body.length; i++) {
          if (head.x == that.snake.body[i].x && head.y == that.snake.body[i].y) {
            alert("Game Over");
            clearInterval(timeId);
          }
        }
      }, 100);
      /** 控制蛇的移动
       * 1.给页面添加keyup事件
       * 2.获取key
       * 3.通过key改变蛇的direction属性
       */
      document.onkeyup = function (e) {
        var keyCode = e.keyCode;
        if (keyCode === 37) {
          if (that.snake.direction === "right") {
            return;
          }
          that.snake.direction = "left";
        } else if (keyCode === 38) {
          if (that.snake.direction === "bottom") {
            return;
          }
          that.snake.direction = "top"
        } else if (keyCode === 39) {
          if (that.snake.direction === "left") {
            return;
          }
          that.snake.direction = "right"
        } else if (keyCode === 40) {
          if (that.snake.direction === "top") {
            return;
          }
          that.snake.direction = "bottom"
        }
      }
    }
  }
  // 暴露的方法添加在window上,一个js只暴露一个核心功能
  window.Game = Game;
})(window)

4.HTML文件

代码如下(示例):

<!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>Document</title>
  <style>
    #map {
      height: 800px;
      width: 1200px;
      background: #ddd;
      margin: 10px auto 20px auto;
      position: relative;
    }

    input[type="button"] {
      background: #409eff;
      color: #fff;
      border: none;
      height: 40px;
      padding: 0 16px;
      display: block;
      /*块级元素独占一行*/
      margin: 10px auto;
      border-radius: 2px;
    }

    input[type="button"]:hover {
      background: rgb(121, 188, 255);
    }
    input[type="button"]:focus {
      border:none;
    }
    input[type="button"]:active {
      background: #2a8ef1;
    }
    .total{
      font-size:24px;
      color: #303030;
      width: 1200px;
      margin:20px auto 0px auto;
    }
    .total #score{
      color:rgb(41, 241, 225);
    }
  </style>
</head>

<body>
  <div class="total">分数:<span id="score"></span></div>
  <div id="map"></div>
  <input type="button" value="开始游戏" />
  <script src="./food.js"></script>
  <script src="./snake.js"></script>
  <script src="./game.js"></script>
  <script>
    const map = document.querySelector("#map");
    const btn = document.querySelector("input");
    
    const game = new Game(map);
    game.render();
    btn.onclick = function(){
      game.startGame();
    }
  </script>
</body>

</html>

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值