贪吃蛇js源代码

项目目录如下:

css代码:

#map {
  width: 800px;
  height: 600px;
  background-color: lightgray;
  position: relative;
}

html代码:

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <title>Document</title>
  <link rel="stylesheet" href="css/style.css">
</head>
<body> 
  <div id="map"></div>
  
  <script src="js/index.js"></script>
</body>
</html>

js代码:

// ---------------------Tools--------------------------
;(function () {
  var Tools = {
    getRandom: function (min, max) {
      return Math.floor(Math.random() * (max - min + 1)) +  min;
    }
  }
  // 暴露Tools给window
  window.Tools = Tools;
})()

// -----------------------Food---------------------------
;(function () {
  // 局部作用域
  var position = 'absolute';
  // 记录上一次创建的食物,为删除做准备
  var elements = [];
  function Food(options) {
    options = options || {};
    this.x = options.x || 0;
    this.y = options.y || 0;

    this.width = options.width || 20;
    this.height = options.height || 20;

    this.color = options.color || 'green';
  }

  // 渲染
  Food.prototype.render = function (map) {
    // 删除之前创建的食物
    remove();

    // 随机设置x和y的值
    this.x = Tools.getRandom(0, map.offsetWidth/this.width - 1) * this.width;
    this.y = Tools.getRandom(0, map.offsetHeight/this.height - 1) * this.height;

    // 动态创建div  页面上显示的食物
    var div = document.createElement('div');
    map.appendChild(div);

    elements.push(div);

    // 设置div的样式
    div.style.position = position;
    div.style.left = this.x + 'px';
    div.style.top = this.y + 'px';
    div.style.width = this.width + 'px';
    div.style.height = this.height + 'px';
    div.style.backgroundColor = this.color;
  }

  function remove() {
    for (var i = elements.length - 1; i >= 0; i--) {
      // 删除div
      elements[i].parentNode.removeChild(elements[i]);
      // 删除数组中的元素
      // 删除数组元素
      // 第一个参数,从哪个元素开始删除
      // 第二个参数,删除几个元素
      elements.splice(i, 1);
    }
  }

  // 把Food构造函数  让外部可以访问
  window.Food = Food;
})()

// ---------------------------Snake----------------------
;(function () {
  var position = 'absolute';
  // 记录之前创建的蛇
  var elements = [];
  function Snake(options) {
    options = options || {};
    // 蛇节 的大小
    this.width = options.width || 20;
    this.height = options.height || 20;
    // 蛇移动的方向
    this.direction = options.direction || 'right';
    // 蛇的身体(蛇节)  第一个元素是蛇头
    this.body = [
      {x: 3, y: 2, color: 'red'},
      {x: 2, y: 2, color: 'blue'},
      {x: 1, y: 2, color: 'blue'}
    ];
  }

  Snake.prototype.render = function (map) {
    // 删除之前创建的蛇
    remove();
    // 把每一个蛇节渲染到地图上
    for (var i = 0, len = this.body.length; i < len; i++) {
      // 蛇节
      var object = this.body[i];
      // 
      var div = document.createElement('div');
      map.appendChild(div);

      // 记录当前蛇
      elements.push(div);

      // 设置样式
      div.style.position = position;
      div.style.width = this.width + 'px';
      div.style.height = this.height + 'px';
      div.style.left = object.x * this.width + 'px';
      div.style.top = object.y * this.height + 'px';
      div.style.backgroundColor = object.color;
    }
  }
  // 私有的成员
  function remove() {
    for (var i = elements.length - 1; i >= 0; i--) {
      // 删除div
      elements[i].parentNode.removeChild(elements[i]);
      // 删除数组中的元素
      elements.splice(i, 1);
    }
  }

  // 控制蛇移动的方法
  Snake.prototype.move = function (food, map) {
    // 控制蛇的身体移动(当前蛇节 到 上一个蛇节的位置)
    for (var i = this.body.length - 1; i > 0; i--) {
      this.body[i].x = this.body[i - 1].x;
      this.body[i].y = this.body[i - 1].y;
    }
    // 控制蛇头的移动
    // 判断蛇移动的方向
    var head = this.body[0];
    switch(this.direction) {
      case 'right': 
        head.x += 1;
        break;
      case 'left': 
        head.x -= 1;
        break;
      case 'top':
        head.y -= 1;
        break;
      case 'bottom':
        head.y += 1;
        break;
    }

    // 2.4 判断蛇头是否和食物的坐标重合
    var headX = head.x * this.width;
    var headY = head.y * this.height;
    if (headX === food.x && headY === food.y) {
      // 让蛇增加一节
      // 获取蛇的最后一节
      var last = this.body[this.body.length - 1];
      this.body.push({
        x: last.x,
        y: last.y,
        color: last.color
      })

      // 随机在地图上重新生成食物
      food.render(map);
    }

  }

  // 暴露构造函数给外部
  window.Snake = Snake;
})()

//----------------------Game---------------------------
;(function () {
  var that;  // 记录游戏对象
  function Game(map) {
    this.food = new Food();
    this.snake = new Snake();
    this.map = map;
    that = this;
  }

  Game.prototype.start = function () {
    // 1 把蛇和食物对象,渲染到地图上
    this.food.render(this.map);
    this.snake.render(this.map);
    // 2 开始游戏的逻辑
    // 2.1  让蛇移动起来
    // 2.2  当蛇遇到边界游戏结束
    runSnake();
    // 2.3  通过键盘控制蛇移动的方向
    bindKey();
    // 2.4  当蛇遇到食物 --- 在snake的move方法中处理  
   }

   // 通过键盘控制蛇移动的方向
  function bindKey() {
    // document.onkeydown = function () {};
    document.addEventListener('keydown', function (e) {
      // console.log(e.keyCode);
      // 37 - left
      // 38 - top
      // 39 - right
      // 40 - bottom
      switch (e.keyCode) {
        case 37: 
          this.snake.direction = 'left';
          break;
        case 38:
          this.snake.direction = 'top';
          break;
        case 39:
          this.snake.direction = 'right';
          break;
        case 40:
          this.snake.direction = 'bottom';
          break;
      }
    }.bind(that), false);
  }

   // 私有的函数  让蛇移动
   function runSnake() {
     var timerId = setInterval(function () {
       // 让蛇走一格
       // 在定时器的function中this是指向window对象的
       // this.snake
       // 要获取游戏对象中的蛇属性
       this.snake.move(this.food, this.map);
       this.snake.render(this.map);

        // 2.2  当蛇遇到边界游戏结束
        // 获取蛇头的坐标
        var maxX = this.map.offsetWidth / this.snake.width;
        var maxY = this.map.offsetHeight / this.snake.height;
        var headX = this.snake.body[0].x;
        var headY = this.snake.body[0].y;
        if (headX < 0 || headX >= maxX) {
          alert('Game Over');
          clearInterval(timerId);
        }

        if (headY < 0 || headY >= maxY) {
          alert('Game Over');
          clearInterval(timerId);
        }
     }.bind(that), 150);
   }

  // 暴露构造函数给外部
  window.Game = Game;
})()

// -------------------调用------------------
;(function () {
  var map = document.getElementById('map');
  var game = new Game(map);
  game.start();
})()





评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值