原生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 相关文章推荐
js类的静态属性和实例属性的理解
Oct 01 Javascript
页面中iframe相互传值传参
Dec 13 Javascript
JS获得图片alt信息的方法
Apr 01 Javascript
使用Javascript写的2048小游戏
Nov 25 Javascript
jquery 标签 隔若干行加空白或者加虚线的方法
Dec 07 Javascript
angular或者js怎么确定选中ul中的哪几个li
Aug 16 Javascript
jQuery简单实现向列表动态添加新元素的方法示例
Dec 25 jQuery
详解Vue单元测试Karma+Mocha学习笔记
Jan 31 Javascript
JS中min函数实例讲解
Feb 18 Javascript
基于node+websocket+html实现腾讯课堂聊天室聊天功能
Mar 04 Javascript
浅谈Vue3 Composition API如何替换Vue Mixins
Apr 29 Javascript
JS中箭头函数与this的写法和理解
Jan 14 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 radio 单选框获取与保持值的实现代码
2010/05/15 PHP
PHP+redis实现添加处理投票的方法
2015/11/14 PHP
Symfony2开发之控制器用法实例分析
2016/02/05 PHP
基于逻辑运算的简单权限系统(实现) JS 版
2007/03/24 Javascript
javascript+xml技术实现分页浏览
2008/07/27 Javascript
jquery ajax提交表单数据的两种实现方法
2010/04/29 Javascript
JavaScript prototype属性使用说明
2010/05/13 Javascript
JS模拟面向对象全解(一、类型及传递)
2011/07/13 Javascript
各种常用的JS函数整理
2013/10/25 Javascript
javascript对下拉列表框(select)的操作实例讲解
2013/11/29 Javascript
javascript实现3D变换的立体圆圈实例
2015/08/06 Javascript
前端跨域的几种解决方式总结(推荐)
2017/08/16 Javascript
Angular搜索 过滤 批量删除 添加 表单验证功能集锦(实例代码)
2017/10/25 Javascript
JS排序算法之希尔排序与快速排序实现方法
2017/12/12 Javascript
使用Vuex实现一个笔记应用的方法
2018/03/13 Javascript
JS+html5实现异步上传图片显示上传文件进度条功能示例
2019/11/09 Javascript
echarts 使用formatter 修改鼠标悬浮事件信息操作
2020/07/20 Javascript
[01:14]DOTA2亚洲邀请赛 ShowOpen
2015/02/07 DOTA
[00:37]DOTA2上海特级锦标赛 Secert 战队宣传片
2016/03/03 DOTA
Python探索之ModelForm代码详解
2017/10/26 Python
python 实现语音聊天机器人的示例代码
2018/12/02 Python
Python获取时间戳代码实例
2019/09/24 Python
Python udp网络程序实现发送、接收数据功能示例
2019/12/09 Python
Python基于Dlib的人脸识别系统的实现
2020/02/26 Python
解决python DataFrame 打印结果不换行问题
2020/04/09 Python
python中判断数字是否为质数的实例讲解
2020/12/06 Python
纯CSS3实现扇形动画菜单(简化版)实例源码
2017/01/17 HTML / CSS
HTML5之WebGL 3D概述(上)—WebGL原生开发开启网页3D渲染新时代
2013/01/31 HTML / CSS
HTML5地理定位实例
2014/10/15 HTML / CSS
伊利莎白雅顿官网:Elizabeth Arden
2016/10/10 全球购物
生物专业个人自荐信范文
2013/11/29 职场文书
十佳青年事迹材料
2014/08/21 职场文书
2016年春节慰问信息
2015/03/25 职场文书
2015年党务工作者个人工作总结
2015/10/22 职场文书
营销策划分析:怎么策划才能更好销量产品?
2019/09/04 职场文书
Elasticsearch 索引操作和增删改查
2022/04/19 Python