原生js实现贪食蛇小游戏的思路详解


Posted in Javascript onNovember 26, 2019

先不多说先上图

原生js实现贪食蛇小游戏的思路详解

下面是代码部分(这里你可以根据需要改变蛇头和身体还有食物的图片,然后默认的样式是使用纯颜色的如果没有更改我的背景图片的话------改这些图开始是想搞笑一下朋友哈哈哈,请不要在意哈),还有操作键是使用 ↑ ↓ ← → )

<!DOCTYPE html>
<html>
<head lang="en">
  <meta charset="UTF-8">
  <title>贪食蛇</title>
  <style>
    .map {
      width: 800px;
      height: 600px;
      background-color: #ccc;
      position: relative;
      left: 50%;
      transform: translate(-50%);
    }
    #dv {
      color: whitesmoke;
      font-weight: 700;
      text-align: center;
      line-height: 50px;
      width: 150px;
      height: 50px;
      position: absolute;
      background-color: orange;
      border-radius: 10px;
      top: 50%;
      left: 50%;
      transform: translate(-50%);
      cursor: pointer;
    }
  </style>
</head>
<body>
  <div class="map">
    <div id="dv">开始游戏</div>
  </div>
  <script>
    //食物:是一个对象,有宽,有高,有颜色,有横纵坐标
    //自调用函数
    (function () {
      var element = []; //用来保存每个小方块食物的
      function Food(x, y, width, height, color) {
        this.x = x || 0;
        this.y = y || 0;
        this.width = width || 20;
        this.height = height || 20;
        this.color = color || "green";
      }
      //为原型添加初始化的方法(作用:在页面上显示这个食物)
      //因为食物要在地图上显示,所以,需要地图的这个参数(map--就是页面上的.class=map的这个div)
      Food.prototype.init = function (map) {
        //先删除这个小食物
        //外部无法访问,此函数在自调用函数里面
        remove();
        //创建div
        var div = document.createElement("div");
        //把div加到map里面
        map.appendChild(div);
        //获取div的样式
        div.style.width = this.width + "px";
        div.style.height = this.height + "px";
        div.style.backgroundColor = this.color;
        //脱离文档流
        div.style.position = "absolute";
        //横纵坐标先停止----随机产生
        this.x = parseInt(Math.random() * (map.offsetWidth / this.width)) * this.width;
        this.y = parseInt(Math.random() * (map.offsetHeight / this.height)) * this.height;
        div.style.left = this.x + "px";
        div.style.top = this.y + "px";
        //把div加入element数组中
        element.push(div);
        //改变食物的样式---改成自己喜欢的东西
        div.style.backgroundImage = "url(" + "../images/shi.png" + ")";
        div.style.backgroundRepeat = "no-repaet";
        div.style.backgroundSize = "cover";
      };
      //私有函数
      function remove() {
        for (var i = 0; i < element.length; i++) {
          var ele = element[i];
          //找到这个子元素的父级元素,然后删除这个子元素
          ele.parentNode.removeChild(ele);
          //再次把element中的这个子元素删除
          element.splice(i, 1);
        }
      }
      //把Food暴露给window,外部可以使用
      window.Food = Food;
    }());
    //自调用函数---小蛇
    (function () {
      //存放小蛇的每个身体部分
      var element = [];
      //小蛇的构造函数
      function Snake(width, height, driection) {
        this.width = width || 20;
        this.height = height || 20;
        //小蛇的身体
        this.body = [{
            x: 3,
            y: 2,
            color: "red"
          },
          {
            x: 2,
            y: 2,
            color: "orange"
          },
          {
            x: 1,
            y: 2,
            color: "orange"
          }
        ];
        //方向
        this.driection = driection || "right";
      }
      //为原型添加方法---小蛇初始化的方法
      Snake.prototype.init = function (map) {
        //先删除之前的小蛇
        remove();
        //循环遍历创建div
        for (var i = 0; i < this.body.length; i++) {
          //数组中的每个数组元素都是一个对象
          var obj = this.body[i];
          //创建div
          var div = document.createElement("div");
          //把div加入地图map中
          map.appendChild(div);
          //设置div的样式
          div.style.position = "absolute";
          div.style.width = this.width + "px";
          div.style.height = this.height + "px";
          //横纵坐标
          div.style.left = obj.x * this.width + "px";
          div.style.top = obj.y * this.height + "px";
          //背景颜色
          div.style.backgroundColor = obj.color;
          //方向还没定
          //把div加入到element数组中---目的是为了删除
          //把div加入数组中
          element.push(div);
          //更改头部的----变成图片
          if (i == 0) {
            div.style.backgroundImage = "url(" + "../images/tou_03.png" + ")";
            div.style.backgroundRepeat = "no-repaet";
            div.style.backgroundSize = "cover";
          }
          //更改尾巴的样式照片
          if (i != 0) {
            div.style.backgroundImage = "url(" + "../images/shi.png" + ")";
            div.style.backgroundRepeat = "no-repaet";
            div.style.backgroundSize = "cover";
          }
        }
      };
      //为原型添加方法---小蛇动起来
      Snake.prototype.move = function (food, map) {
        var i = this.body.length - 1;
        for (; i > 0; i--) {
          this.body[i].x = this.body[i - 1].x;
          this.body[i].y = this.body[i - 1].y;
        }
        //判断方向---改变小蛇的头的坐标位置
        switch (this.driection) {
          case "left":
            this.body[0].x -= 1;
            break;
          case "right":
            this.body[0].x += 1;
            break;
          case "top":
            this.body[0].y -= 1;
            break;
          case "bottom":
            this.body[0].y += 1;
            break;
        }
        //判断有没有吃到食物
        //小蛇的头的坐标和食物的坐标一致
        var headX = this.body[0].x * this.width;
        var headY = this.body[0].y * this.height;
        //判断小蛇的头和食物坐标是否相同
        if (headX == food.x && headY == food.y) {
          //获取小蛇的最后的尾巴
          var last = this.body[this.body.length - 1];
          //把最后的蛇尾复制一个,重新的加入到小蛇的body中
          this.body.push({
            x: last.x,
            y: last.y,
            color: last.color
          });
          //把食物删除,重新初始化食物
          food.init(map);
        }
      };
      //删除小蛇的私有函数
      function remove() {
        //获取数组
        var i = element.length - 1;
        for (; i >= 0; i--) {
          var ele = element[i];
          //从map地图上删除这个子元素div
          ele.parentNode.removeChild(ele);
          element.splice(i, 1);
        }
      }
      window.Snake = Snake;
    }());
    //自调用函数---游戏对象
    (function () {
      var that = null;
      //游戏的构造函数
      function game(map) {
        this.food = new Food(); //食物对象
        this.snake = new Snake(); //小蛇对象
        this.map = map; //地图
        that = this;
      }
      game.prototype.init = function () {
        //初始化游戏
        //食物初始化
        this.food.init(this.map);
        //小蛇初始化
        this.snake.init(this.map);
        that = this;
        document.getElementById("dv").onclick = function () {
          document.getElementById("dv").style.display = "none";
          //调用小蛇移动的方法
          that.runSnake(that.food, that.map);
          //调用按键的方法
          that.bindKey();
        }.bind(that);
      };
      //添加原型方法---设置小蛇可以自动跑起来
      game.prototype.runSnake = function (food, map) {
        //自动的去移动
        var time = 90;
        var fn = function () {
          //此时this是window
          //移动小蛇
          this.snake.move(food, map);
          //初始化小蛇
          this.snake.init(map);
          //横坐标的最大值
          var maxX = map.offsetWidth / this.snake.width;
          //纵坐标的最大值
          var maxY = map.offsetHeight / this.snake.height;
          //小蛇的头的坐标
          var headX = this.snake.body[0].x;
          var headY = this.snake.body[0].y;
          //判断 横坐标 有没撞墙
          if (headX < 0 || headX >= maxX) {
            //撞墙停止定时器
            clearInterval(timeId);
            alert("游戏结束");
            location.reload();
          }
          //判断 纵坐标 有没撞墙
          if (headY < 0 || headY >= maxY) {
            clearInterval(timeId);
            alert("游戏结束");
            location.reload();
          }
          //判断 小蛇的头部 有没有 撞到自己
          for (let i = 1; i < this.snake.body.length; i++) {
            let x = this.snake.body[i].x;
            let y = this.snake.body[i].y;
            if (headX === x && headY === y) {
              clearInterval(timeId);
              alert("游戏结束");
              location.reload();
            }
          }
          //增加游戏难度,判断 到达一定数量的时候 加速
          switch (true) {
            case 5 <= this.snake.body.length && this.snake.body.length <= 10:
              clearInterval(timeId);
              time = 60;
              timeId = setInterval(fn, time);
              break;
            case 10 <= this.snake.body.length && this.snake.body.length <= 15:
              clearInterval(timeId);
              time = 40;
              timeId = setInterval(fn, time);
              break;
            case 15 <= this.snake.body.length:
              clearInterval(timeId);
              time = 30;
              timeId = setInterval(fn, time);
              break;
          }
          console.log(this.snake.body.length + "--" + "time:" + time);
        }.bind(that);
        //定时器小蛇自运动
        var timeId = setInterval(fn, time);
      };
      //添加原型方法---设置用户按键,改变小蛇移动的方向
      game.prototype.bindKey = function () {
        //获取用户的按键,改变小蛇的移动方向
        document.addEventListener("keydown", function (e) {
          //获取按键的值并进行判断是,改变小蛇移动的方向
          switch (e.keyCode) {
            //没有bind方法时此时的this指向的是documen
            case 37:
              if (this.snake.driection != "right") {
                this.snake.driection = "left";
              }
              break;
            case 38:
              if (this.snake.driection != "bottom") {
                this.snake.driection = "top";
              }
              break;
            case 39:
              if (this.snake.driection != "left") {
                this.snake.driection = "right";
              }
              break;
            case 40:
              if (this.snake.driection != "top") {
                this.snake.driection = "bottom";
              }
              break;
          }
        }.bind(that), false);
      };
      //把game暴露给window,外部就可以访问game对象
      window.game = game;
    }());
    //初始化游戏对象
    var gm = new game(document.querySelector(".map"));
    //初始化游戏---开始游戏
    gm.init();
  </script>
</body>
</html>

总结

以上所述是小编给大家介绍的原生js实现贪食蛇小游戏的思路详解,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对三水点靠木网站的支持!
如果你觉得本文对你有帮助,欢迎转载,烦请注明出处,谢谢!

Javascript 相关文章推荐
javascript div 遮罩层封锁整个页面
Jul 10 Javascript
jquery中ajax函数执行顺序问题之如何设置同步
Feb 28 Javascript
BootStrap Table 获取同行不同列元素的方法
Dec 19 Javascript
easyUI实现类似搜索框关键词自动提示功能示例代码
Dec 27 Javascript
实例讲解DataTables固定表格宽度(设置横向滚动条)
Jul 11 Javascript
jQuery实现拼图小游戏(实例讲解)
Jul 24 jQuery
基于express中路由规则及获取请求参数的方法
Mar 12 Javascript
Vue.js 实现微信公众号菜单编辑器功能(二)
May 08 Javascript
vue实现多个元素或多个组件之间动画效果
Sep 25 Javascript
微信小程序使用npm支持踩坑
Nov 07 Javascript
Vue 实现html中根据类型显示内容
Oct 28 Javascript
javascript实现倒计时关闭广告
Feb 09 Javascript
高效jQuery选择器的5个技巧实例分析
Nov 26 #jQuery
JavaScript计算正方形面积
Nov 26 #Javascript
javaScript中indexOf用法技巧
Nov 26 #Javascript
浅谈Node新版本13.2.0正式支持ES Modules特性
Nov 25 #Javascript
微信小程序实现按字母排列选择城市功能
Nov 25 #Javascript
JS实现点击下拉列表文本框中出现对应的网址,点击跳转按钮实现跳转
Nov 25 #Javascript
jquery使用echarts实现有向图可视化功能示例
Nov 25 #jQuery
You might like
用PHP制作静态网站的模板框架(三)
2006/10/09 PHP
PHP加Nginx实现动态裁剪图片方案
2014/03/10 PHP
php可应用于面包屑导航的迭代寻找家谱树实现方法
2015/02/02 PHP
根据分辩率调用不同的CSS.
2007/01/08 Javascript
Javascript 陷阱 window全局对象
2008/11/26 Javascript
WordPress 照片lightbox效果的运用几点
2009/06/22 Javascript
javascript demo 基本技巧
2009/12/18 Javascript
AJAX的跨域与JSONP(为文章自动添加短址的功能)
2010/01/17 Javascript
获取css样式表内样式的js函数currentStyle(IE),defaultView(FF)
2011/02/14 Javascript
jquery模拟SELECT下拉框取值效果
2013/10/23 Javascript
jQuery拖拽div实现思路
2014/02/19 Javascript
director.js实现前端路由使用实例
2015/02/03 Javascript
基于AngularJS+HTML+Groovy实现登录功能
2016/02/17 Javascript
深入理解jquery自定义动画animate()
2016/05/24 Javascript
JS碰撞运动实现方法详解
2016/12/15 Javascript
mpvue全局引入sass文件的方法步骤
2019/03/06 Javascript
详解vue移动端项目代码拆分记录
2019/03/15 Javascript
vue-cli 项目打包完成后运行文件路径报错问题
2019/07/19 Javascript
layui实现左侧菜单点击右侧内容区显示
2019/07/26 Javascript
python机器学习实战之最近邻kNN分类器
2017/12/20 Python
程序员写Python时的5个坏习惯,你有几条?
2018/11/26 Python
详解python 3.6 安装json 模块(simplejson)
2019/04/02 Python
django实现支付宝支付实例讲解
2019/10/17 Python
零基础小白多久能学会python
2020/06/22 Python
Python colormap库的安装和使用详情
2020/10/06 Python
交通安全教育制度
2014/02/02 职场文书
《草原》教学反思
2014/02/15 职场文书
运动会广播稿150字(9篇)
2014/09/20 职场文书
2014年旅游局法制宣传日活动总结
2014/11/01 职场文书
2014旅游局党组书记党建工作汇报材料
2014/11/02 职场文书
2014年科室工作总结
2014/11/20 职场文书
2015年全民国防教育日活动总结
2015/03/23 职场文书
小学重阳节活动总结
2015/03/24 职场文书
职工趣味运动会开幕词
2016/03/04 职场文书
迎客户欢迎词三篇
2019/09/27 职场文书
MySQL之DML语言
2021/04/05 MySQL