基于javascript实现贪吃蛇小游戏


Posted in Javascript onNovember 25, 2019

本文实例为大家分享了js贪吃蛇游戏的具体代码,供大家参考,具体内容如下

先不多说先上图

基于javascript实现贪吃蛇小游戏

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

<!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>

我已经尽量给以上代码注上注释。希望能帮到更多朋友更好的理解贪食蛇游戏的实现思路!

小编还为大家准备了精彩的专题:javascript经典小游戏汇总

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持三水点靠木。

Javascript 相关文章推荐
javascript之函数直接量(function(){})()
Jun 29 Javascript
深入理解JQuery keyUp和keyDown的区别
Dec 12 Javascript
jquery进行数组遍历如何跳出当前的each循环
Jun 05 Javascript
JavaScript中判断页面关闭、页面刷新的实现代码
Aug 27 Javascript
JavaScript中Window对象的属性及事件
Dec 25 Javascript
jQuery常用知识点总结以及平时封装常用函数
Feb 23 Javascript
iscroll碰到Select无法选择下拉刷新的解决办法
May 21 Javascript
Bootstrap 填充Json数据的实例代码
Jan 11 Javascript
深入理解Vue 组件之间传值
Aug 16 Javascript
javascript动态创建对象的属性详解
Nov 07 Javascript
JS实现长图上下滚动效果
Mar 19 Javascript
Vue-cli assets SubDirectory及PublicPath区别详解
Aug 18 Javascript
JavaScript This指向问题详解
Nov 25 #Javascript
简单了解JavaScript sort方法
Nov 25 #Javascript
vue使用swiper实现中间大两边小的轮播图效果
Nov 24 #Javascript
通过GASP让vue实现动态效果实例代码详解
Nov 24 #Javascript
JS控制只能输入数字并且最多允许小数点两位
Nov 24 #Javascript
解决Vue.js应用回退或刷新界面时提示用户保存修改问题
Nov 24 #Javascript
Egg Vue SSR 服务端渲染数据请求与asyncData
Nov 24 #Javascript
You might like
php微信公众号开发(4)php实现自定义关键字回复
2016/12/15 PHP
(转载)JavaScript中匿名函数,函数直接量和闭包
2007/05/08 Javascript
JQuery的Alert消息框插件使用介绍
2010/10/09 Javascript
Javascript Web Slider 焦点图示例源码
2013/10/10 Javascript
一个简单的实现下拉框多选的插件可移植性比较好
2014/05/05 Javascript
javascript DIV实现跟随鼠标移动
2020/03/19 Javascript
整理AngularJS框架使用过程当中的一些性能优化要点
2016/03/05 Javascript
JS组件系列之Bootstrap table表格组件神器【终结篇】
2016/05/10 Javascript
angularJS 如何读写缓冲的方法(推荐)
2016/08/06 Javascript
JS匿名函数类生成方式实例分析
2016/11/26 Javascript
AngularJS使用ng-app自动加载bootstrap框架问题分析
2017/01/04 Javascript
JS逻辑运算符短路操作实例分析
2018/07/09 Javascript
JavaScript解决浮点数计算不准确问题的方法分析
2018/07/09 Javascript
vue router 源码概览案例分析
2018/10/09 Javascript
angularjs http与后台交互的实现示例
2018/12/21 Javascript
5分钟快速看懂ES6中的反射与代理
2019/12/19 Javascript
JavaScript实现轮播图特效
2020/04/10 Javascript
关于angular浏览器兼容性问题的解决方案
2020/07/26 Javascript
[04:26]2014DOTA2国际邀请赛-Newbee顺利进入胜者组决赛 独家专访战神7
2014/07/19 DOTA
Python模拟登录验证码(代码简单)
2016/02/06 Python
浅谈scrapy 的基本命令介绍
2017/06/13 Python
Python探索之创建二叉树
2017/10/25 Python
将pytorch转成longtensor的简单方法
2020/02/18 Python
python GUI库图形界面开发之PyQt5打印控件QPrinter详细使用方法与实例
2020/02/28 Python
Canvas与图片压缩的示例代码
2017/11/28 HTML / CSS
Waterford英国官方网站:世界上最受欢迎的优质水晶品牌
2019/08/17 全球购物
哈萨克斯坦最大的时装、鞋子和配饰在线商店:Lamoda.kz
2019/11/19 全球购物
Linux常见面试题
2013/03/18 面试题
测绘工程专业求职信
2014/07/15 职场文书
幼儿园六一儿童节活动方案
2014/08/26 职场文书
2015大学生实训报告
2014/11/05 职场文书
导游词之太行山青龙峡
2020/01/14 职场文书
5种方法告诉你如何使JavaScript 代码库更干净
2021/09/15 Javascript
Python实现文字pdf转换图片pdf效果
2022/04/03 Python
MyBatis在注解上使用动态SQL方式(@select使用if)
2022/07/07 Java/Android
Nginx如何配置根据路径转发详解
2022/07/23 Servers