原生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 命名空间以提高代码重用性
Nov 13 Javascript
js window.onload 加载多个函数的方法
Nov 02 Javascript
改变javascript函数内部this指针指向的三种方法
Apr 23 Javascript
判断目标是否是window,document,和拥有tagName的Element的代码
May 31 Javascript
jquery里的正则表达式说明
Aug 03 Javascript
Jjcarousellite 实现图片列表滚动的简单实例
Nov 29 Javascript
node.js入门教程迷你书、node.js入门web应用开发完全示例
Apr 06 Javascript
JS模拟的Map类实现方法
Jun 17 Javascript
JS实现漂亮的时间选择框效果
Aug 20 Javascript
vue-cli3.0+element-ui上传组件el-upload的使用
Dec 03 Javascript
浅析微信小程序modal弹窗关闭默认会执行cancel问题
Oct 14 Javascript
深入分析jQuery.one() 函数
Jun 03 jQuery
高效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面向对象学习笔记之二 生成对象的设计模式
2012/10/06 PHP
探讨file_get_contents与curl效率及稳定性的分析
2013/06/06 PHP
PHP中类的继承和用法实例分析
2016/05/24 PHP
PHP获取当前执行php文件名的代码
2017/03/02 PHP
PHP学习笔记之session
2018/05/06 PHP
Javascript日期对象的dateAdd与dateDiff方法
2008/11/18 Javascript
解决IE6的PNG透明JS插件使用介绍
2013/04/17 Javascript
jQuery中.live()方法的用法深入解析
2013/12/30 Javascript
一个JavaScript用逗号分割字符串实例
2014/09/22 Javascript
javaScript中Math()函数注意事项
2015/06/18 Javascript
jQuery获取单击节点对象的方法
2016/06/02 Javascript
JavaScript SHA1加密算法实现详细代码
2016/10/06 Javascript
JS中split()用法(将字符串按指定符号分割成数组)
2016/10/24 Javascript
js 递归和定时器的实例解析
2017/02/03 Javascript
初探js和简单隐藏效果的实例
2017/11/23 Javascript
JavaScript实现沿五角星形线摆动的小圆实例详解
2020/07/28 Javascript
20招让你的Python飞起来!
2016/09/27 Python
python3.5 email实现发送邮件功能
2018/05/22 Python
python计算列表内各元素的个数实例
2018/06/29 Python
python 求1-100之间的奇数或者偶数之和的实例
2019/06/11 Python
python字典嵌套字典的情况下找到某个key的value详解
2019/07/10 Python
python递归下载文件夹下所有文件
2019/08/31 Python
关于Pytorch的MLP模块实现方式
2020/01/07 Python
基于tensorflow指定GPU运行及GPU资源分配的几种方式小结
2020/02/03 Python
基于Python生成个性二维码过程详解
2020/03/05 Python
PYQT5 vscode联合操作qtdesigner的方法
2020/03/24 Python
从python读取sql的实例方法
2020/07/21 Python
ORLY官网:美国专业美甲一线品牌
2019/12/11 全球购物
JPA面试常见问题
2016/11/14 面试题
命名空间(namespace)和程序集(Assembly)有什么区别
2015/09/25 面试题
自主招生自荐信
2013/12/08 职场文书
高一军训的心得体会
2014/09/01 职场文书
乡镇党的群众路线教育实践活动个人对照检查材料
2014/09/23 职场文书
2015年社区宣传工作总结
2015/05/20 职场文书
2015年教师业务工作总结
2015/05/26 职场文书
《群青的幻想曲》京力秋树角色PV公开
2022/04/08 日漫