原生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 相关文章推荐
网页自动刷新,不产生嗒嗒声的一个解决方法
Mar 27 Javascript
css把超出的部分显示为省略号的方法兼容火狐
Jul 23 Javascript
jQeury淡入淡出需要注意的问题
Sep 08 Javascript
JAVASCRIPT函数作用域和提前声明 分享
Aug 22 Javascript
JavaScript匿名函数与委托使用示例
Jul 22 Javascript
VC调用javascript的几种方法(推荐)
Aug 09 Javascript
vue2实现移动端上传、预览、压缩图片解决拍照旋转问题
Apr 13 Javascript
jQuery基于cookie实现换肤功能实例
Oct 14 jQuery
vue环境搭建简单教程
Nov 07 Javascript
解决vue 更改计算属性后select选中值不更改的问题
Mar 02 Javascript
手把手教你用Node.js爬虫爬取网站数据的方法
Jul 05 Javascript
前端路由&amp;webpack基础配置详解
Jun 10 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模拟HTTP认证
2006/10/09 PHP
发布一个用PHP fsockopen写的HTTP下载的类
2007/02/22 PHP
ASP和PHP都是可以删除自身的
2007/04/09 PHP
php实现微信公众号主动推送消息
2015/12/31 PHP
nodejs开发微博实例
2015/03/25 NodeJs
如何在JS中实现相互转换XML和JSON
2016/07/19 Javascript
JS实现重新加载当前页面或者父页面的几种方法
2016/11/30 Javascript
简单几步实现返回顶部效果
2016/12/05 Javascript
JS仿QQ好友列表展开、收缩功能(第二篇)
2017/07/07 Javascript
jQuery实现的鼠标滚轮控制图片缩放功能实例
2017/10/14 jQuery
ES6使用export和import实现模块化的方法
2018/09/10 Javascript
详解基于electron制作一个node压缩图片的桌面应用
2019/01/29 Javascript
少女风vue组件库的制作全过程
2019/05/15 Javascript
微信小程序下拉框搜索功能的实现方法
2019/07/31 Javascript
webpack HappyPack实战详解
2019/10/08 Javascript
webpack DllPlugin xxx is not defined解决办法
2019/12/13 Javascript
ant-design-vue 快速避坑指南(推荐)
2020/01/21 Javascript
通过代码实例展示Python中列表生成式的用法
2015/03/31 Python
Python利用多进程将大量数据放入有限内存的教程
2015/04/01 Python
在Python中marshal对象序列化的相关知识
2015/07/01 Python
实例Python处理XML文件的方法
2015/08/31 Python
django 发送手机验证码的示例代码
2018/04/25 Python
Python Numpy库安装与基本操作示例
2019/01/08 Python
pandas数据筛选和csv操作的实现方法
2019/07/02 Python
django的csrf实现过程详解
2019/07/26 Python
详解PyTorch中Tensor的高阶操作
2019/08/18 Python
Python 脚本拉取 Docker 镜像问题
2019/11/10 Python
利用OpenCV中对图像数据进行64F和8U转换的方式
2020/06/03 Python
基于Python+QT的gui程序开发实现
2020/07/03 Python
python基本算法之实现归并排序(Merge sort)
2020/09/01 Python
详解Html5 Canvas画线有毛边解决方法
2018/03/01 HTML / CSS
Timberland澳大利亚官网:全球领先的户外品牌
2019/12/10 全球购物
技术总监个人的自我评价范文
2013/12/18 职场文书
篮球比赛口号
2014/06/10 职场文书
铣床操作工岗位职责
2014/06/13 职场文书
Python pandas之求和运算和非空值个数统计
2021/08/07 Python