js面向对象开发贪吃蛇

人生如行路,一路艰辛,一路风景。你的目光所及,就是你的人生境界。给自己一份坚强,擦干眼泪;给自己一份自信,不卑不亢;给自己一份洒脱,悠然前行
-- 本文章出自拉勾教育大前端

前言:开局一张图,内容全靠编

  • 今天我们手动写一个规范的面向对象开发的小游戏,用到的唯一工具就是vscode以及任何一个编辑器就可以。
  • 贪吃蛇这款游戏在我们很小的时候都玩过,立马的机制和游戏内容想必大家都非常清楚,这里我们就不细说,相信写完这游戏大家都不会再想玩这个游戏了吧!
  • 游戏规则就是贪吃蛇碰到边界游戏结束,贪吃蛇碰到自己游戏结束,贪吃蛇碰到围墙游戏结束

贪吃蛇小游戏

一、构建需要的对象

  • 因为食物对象需要随机出现,所以我们需要封装随机的函数tools.js文件
    (function(){
      var Tools = {
      getRandom: function(min,max){
        min = Math.ceil(min);
        max = Math.floor(max);
        return Math.floor(Math.random() * (max - min + 1)) + min;
      },
      getColor: function(){
        var r = this.getRandom(0,255);
        var g = this.getRandom(0,255);
        var b = this.getRandom(0,255);
        return "rgb(" + r + "," + g + "," + b + ")"; 
      }
    };
    //封装作用域需要把函数暴露出去
     window.Tools = Tools;
    })();
    
  • 封装食物对象,食物对象包括渲染食物、创造食物和删除食物的方法food.js文件
(function(){
  var ps = "absolute";
  // 食物对象
  function Food(option){
    //避免类型不对
    option = option instanceof Object ? option : {};
    //构造属性
    this.width = option.width || 20;
    this.height = option.height || 20;
    this.color = option.color || "green";
    this.x = option.x || 0;
    this.y = option.y || 0;
    //添加个数组,用来接受创建的元素(考虑多个food的情况)
    this.elements = [];
  }
  // 创造食物
  Food.prototype.render = function(map){
    //构造新元素添加到map中
    var ele = document.createElement("div");
    //让xy随机
    this.x = Tools.getRandom(0,map.clientWidth / this.width - 1) * this.width;
    this.y = Tools.getRandom(0,map.clientHeight / this.height - 1) * this.height;
    //构造新元素属性
    ele.style.width = this.width + "px";
    ele.style.height = this.height + "px"
    ele.style.backgroundColor = this.color;
    ele.style.left = this.x + "px";
    ele.style.top = this.y + "px"; 
    ele.style.position = ps;
    map.appendChild(ele);
    this.elements.push(ele); 
  }
  //删除食物
  Food.prototype.remove = function(map, i){
    // 1.删除map中的元素
    map.removeChild(this.elements[i]);
    // 2.删除数组中项
    this.elements.splice(i, 1);
  }
  window.Food = Food;
})();
  • 封装蛇的对象,创建蛇,蛇只有一个,蛇身有很多个,因此要创建蛇运动的方法,并删除蛇上一次运动的轨迹snake.js文件
(function(){
  var ps = "absolute";
  // 创造蛇的对象
  function Snake(option){
    option = option instanceof Object ? option : {};
    this.width = option.width || 20;
    this.height = option.height || 20;
    //蛇的数据
    this.body = [
      //蛇头
      {x: 3,y: 2, color: "red"},
      //蛇身
      {x: 2,y: 2, color: "blue"},
      {x: 1,y: 2, color: "blue"},
    ];
    // 蛇移动的方向
    this.direction = "right";
    this.elements = [];
  }
  // 实例化蛇
  Snake.prototype.render = function (map){
    // 遍历body
    for(var i = 0,len = this.body.length; i < len; i++){
      // 用piece记录每项的值
      var piece = this.body[i];
      //在map上渲染新元素
      var ele = document.createElement("div");
      ele.style.width = this.width + "px";
      ele.style.height = this.height + "px";
      ele.style.left = piece.x * this.width + "px";
      ele.style.top = piece.y * this.height + "px";
      ele.style.position = ps;
      ele.style.backgroundColor = piece.color;
      map.appendChild(ele);
      this.elements.push(ele);
    }
  }
  // 蛇运动的方法
  Snake.prototype.move = function(){
    // 蛇身的运动方法
    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;
    }
  }
  // 删除蛇上一次运动的轨迹
  Snake.prototype.remove = function(map){
    for(var i = this.elements.length - 1; i >= 0; i--){
      map.removeChild(this.elements[i]);
    }
    this.elements = [];
  }
  window.Snake = Snake;
})();
  • 加载游戏进程,在游戏进程中,定义的所有游戏规则的结果和碰撞方法,包括获取键盘事件操控蛇运动的方法等game.js
(function(){
  function Game(map){
    this.food = new Food();
    this.snake = new Snake();
    this.wall = new Wall();
    this.map = map;
    that = this;
  }
  // 运行游戏并加载
  Game.prototype.start = function(){
    this.food.render(this.map);
    this.food.render(this.map);
    this.wall.render(this.map);
    this.snake.render(this.map);
    runSnake();
    bindkey();
  }
  // 蛇运动的机制
  function bindkey(){
    document.onkeydown = function(e){
      switch (e.keyCode) {
        case 37:
          if(that.snake.direction != "right"){
            that.snake.direction = "left";
          }
          break;
        case 38:
          if(that.snake.direction != "bottom"){
            that.snake.direction = "top";
          }
          break;
        case 39:
          if(that.snake.direction != "left"){
            that.snake.direction = "right";
          }
          break;
        case 40:
          if(that.snake.direction != "top"){
            that.snake.direction = "bottom";
          }
          break;
      }
    }
  }
  function runSnake(){
    var timer = setInterval(function(){
      that.snake.move();
      that.snake.remove(that.map);
      that.snake.render(that.map);
      //最大位置
      var maxX = that.map.offsetWidth / that.snake.width;
      var maxY = that.map.offsetHeight / that.snake.height;
      //当前蛇的位置
      var headX = that.snake.body[0].x;
      var headY = that.snake.body[0].y;
      //蛇的坐标
      var hX = headX * that.snake.width;
      var hY = headY * that.snake.height;
      //判定哪个食物被蛇吃了
      for(var i = 0; i < that.food.elements.length; i++){
        if(that.food.elements[i].offsetLeft === hX && that.food.elements[i].offsetTop === hY){
          //如果蛇头的坐标等于食物的坐标
          //让食物消失,再重新渲染食物
          that.food.remove(that.map,i);
          that.food.render(that.map);
          //添加一个蛇节
          var last = that.snake.body[that.snake.body.length - 1];
          that.snake.body.push({
            x: last.x,
            y: last.y,
            color: last.color
          })
        }
      }
      //判定超出地图范围,游戏结束
      if(headX < 0 || headX >= maxX || headY < 0 || headY >= maxY){
        clearInterval(timer);
        alert("游戏结束");
      }
      //吃到自己死亡,从第五个开始判定.因为4个无法吃到自己,从第5个开始循环
      for(var i = 4; i < that.snake.body.length; i++){
        if(that.snake.body[i].x === headX && that.snake.body[i].y === headY){
          clearInterval(timer);
          alert("游戏结束");
        }
      }
      // 判定撞到红色的墙也会结束游戏
      for (var i = 0; i < that.wall.arrs.length; i++){
        if(headX === that.wall.arrs[i].x && headY === that.wall.arrs[i].y){
          clearInterval(timer);
          alert("游戏结束");
        }
      }
    },150);
  }
  window.Game = Game;
})()

你可能感兴趣的:(js面向对象开发贪吃蛇)