JS实现的贪吃蛇游戏完整实例


Posted in Javascript onJanuary 18, 2019

本文实例讲述了JS实现的贪吃蛇游戏。分享给大家供大家参考,具体如下:

思想:

1、设计蛇:属性有宽、高、方向、状态(有多少节),方法:显示,跑

2、设计食物:属性宽、高

3、显示蛇:根据状态向地图里加元素

4、蛇跑起来:下一节到前一节的位置,蛇头根据方向变,删除原来的蛇,新建蛇;当出界时,死亡,初始化;当蛇头吃到自己的时候,死亡,初始化

5、食物被吃掉,蛇加一节,去掉原来的食物,生成新的食物

6、添加定时器,绑定按键

完整示例:

<!doctype html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta name="viewport"
     content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0">
  <meta http-equiv="X-UA-Compatible" content="ie=edge">
  <title>Document</title>
  <style type="text/css">
    body {
      margin: 0;
      padding: 0;
    }
    .main {
      width: 800px;
      height: 400px;
      margin: 50px auto;
    }
    .btn {
      width: 100px;
      height: 40px;
    }
    .map {
      position: relative;
      width: 800px;
      height: 400px;
      background: #ccc;
    }
  </style>
</head>
<body>
<div class="main">
  <button class="btn" id="begin">开始游戏</button>
  <div class="map" id="map"></div>
  <script type="text/javascript">
    var map = document.getElementById('map');
    // 使用构造方法创建蛇,
    function Snake()
    {
      // 设置蛇的宽、高、默认走的方向
      this.width = 10;
      this.height = 10;
      this.direction = 'right';
      // 记住蛇的状态,当吃完食物的时候,就要加一个,初始为3个小点为一个蛇,
      this.body = [
        {x:2, y:0},  // 蛇头,第一个点
        {x:1, y:0},  // 蛇脖子,第二个点
        {x:0, y:0}  // 蛇尾,第三个点
      ];
      // 显示蛇
      this.display = function() {
        // 创建蛇
        for (var i=0; i<this.body.length; i++) {
          if (this.body[i].x != null) {  // 当吃到食物时,x==null,不能新建,不然会在0,0处新建一个
            var s = document.createElement('div');
            // 将节点保存到状态中,以便于后面删除
            this.body[i].flag = s;
            // 设置宽高
            s.style.width = this.width + 'px';
            s.style.height = this.height + 'px';
            s.style.borderRadius = "50%";
            s.style.background = "rgb(" + Math.floor(Math.random()*256) + "," + Math.floor(Math.random()*256) + "," + Math.floor(Math.random()*256) + ")";
            // 设置位置
            s.style.position = 'absolute';
            s.style.left = this.body[i].x * this.width + 'px';
            s.style.top = this.body[i].y * this.height + 'px';
            // 添加进去
            map.appendChild(s);
          }
        }
      };
      // 让蛇跑起来,后一个元素到前一个元素的位置
      // 蛇头根据方向处理,所以i不能等于0
      this.run = function() {
        // 后一个元素到前一个元素的位置
        for (var i=this.body.length-1; i>0; i--) {
          this.body[i].x = this.body[i-1].x;
          this.body[i].y = this.body[i-1].y;
        }
        // 根据方向处理蛇头
        switch(this.direction)
        {
          case "left":
            this.body[0].x -= 1;
            break;
          case "right":
            this.body[0].x += 1;
            break;
          case "up":
            this.body[0].y -= 1;
            break;
          case "down":
            this.body[0].y += 1;
            break;
        }
        // 判断是否出界,一蛇头判断,出界的话,
        if (this.body[0].x < 0 || this.body[0].x > 79 || this.body[0].y < 0 || this.body[0].y > 39) {
          clearInterval(timer);  // 清除定时器,
          alert("你瞎吗?撞死了!");
          // 删除旧的
          for (var i=0; i<this.body.length; i++) {
            if (this.body[i].flag != null) {  // 如果刚吃完就死掉,会加一个值为null的
              map.removeChild(this.body[i].flag);
            }
          }
          this.body = [  // 回到初始状态,
            {x:2, y:0},
            {x:1, y:0},
            {x:0, y:0}
          ];
          this.direction = 'right';
          this.display();  // 显示初始状态
          return false;  // 结束
        }
        // 判断蛇头吃到食物,xy坐标重合,
        if (this.body[0].x == food.x && this.body[0].y == food.y) {
          // 蛇加一节,因为根据最后节点定,下面display时,会自动赋值的
          this.body.push({x:null, y:null, flag: null});
          // 清除食物,重新生成食物
          map.removeChild(food.flag);
          food.display();
        }
        // 吃到自己死亡,从第五个开始与头判断,因为前四个永远撞不到
        for (var i=4; i<this.body.length; i++) {
          if (this.body[0].x == this.body[i].x && this.body[0].y == this.body[i].y) {
            clearInterval(timer);  // 清除定时器,
            alert("傻子!你怎么能吃自己呢?");
            // 删除旧的
            for (var i=0; i<this.body.length; i++) {
              if (this.body[i].flag != null) {  // 如果刚吃完就死掉,会加一个值为null的
                map.removeChild(this.body[i].flag);
              }
            }
            this.body = [  // 回到初始状态,
              {x:2, y:0},
              {x:1, y:0},
              {x:0, y:0}
            ];
            this.direction = 'right';
            this.display();  // 显示初始状态
            return false;  // 结束
          }
        }
        // 先删掉初始的蛇,在显示新蛇
        for (var i=0; i<this.body.length; i++) {
          if (this.body[i].flag != null) {  // 当吃到食物时,flag是等于null,且不能删除
            map.removeChild(this.body[i].flag);
          }
        }
        // 重新显示蛇
        this.display();
      }
    }
    // 构造食物
    function Food()
    {
      this.width = 10;
      this.height = 10;
      this.display = function() {
        var f = document.createElement('div');
        this.flag = f;
        f.style.width = this.width + 'px';
        f.style.height = this.height + 'px';
        f.style.background = 'red';
        f.style.borderRadius = '50%';
        f.style.position = 'absolute';
        this.x = Math.floor(Math.random()*80);
        this.y = Math.floor(Math.random()*40);
        f.style.left = this.x * this.width + 'px';
        f.style.top = this.y * this.height + 'px';
        map.appendChild(f);
      }
    }
    var snake = new Snake();
    var food = new Food();
    snake.display();  // 初始化显示
    food.display();
    // 给body加按键事件,上下左右
    document.body.onkeydown = function(e) {
      // 有事件对象就用事件对象,没有就自己创建一个,兼容低版本浏览器
      var ev = e || window.event;
      switch(ev.keyCode)
      {
        case 38:
          if (snake.direction != 'down') {  // 不允许返回,向上的时候不能向下
            snake.direction = "up";
          }
          break;
        case 40:
          if (snake.direction != "up") {
            snake.direction = "down";
          }
          break;
        case 37:
          if (snake.direction != "right") {
            snake.direction = "left";
          }
          break;
        case 39:
          if (snake.direction != "left") {
            snake.direction = "right";
          }
          break;
      }
    };
    // 点击开始时,动起来
    var begin = document.getElementById('begin');
    var timer;
    begin.onclick = function() {
      clearInterval(timer);
      // timer = setInterval(snake.run(), 500);  // 先执行run函数,把执行得到的结果,每500毫秒执行一次,不会在执行内部代码
      timer = setInterval("snake.run()", 500); // 小技巧,每500毫秒执行字符串,字符串执行内部代码
    };
  </script>
</div>
</body>
</html>

使用在线HTML/CSS/JavaScript代码运行工具:http://tools.3water.com/code/HtmlJsRun测试上述代码,可得到如下运行效果:

JS实现的贪吃蛇游戏完整实例

希望本文所述对大家JavaScript程序设计有所帮助。

Javascript 相关文章推荐
Javascript Web Slider 焦点图示例源码
Oct 10 Javascript
JS获取几种URL地址的方法小结
Feb 26 Javascript
js实现弹出窗口、页面变成灰色并不可操作的例子分享
May 10 Javascript
js点击文本框弹出可选择的checkbox复选框
Feb 03 Javascript
详解JavaScript中的事件流和事件处理程序
May 20 Javascript
js实现五星评价功能
Mar 08 Javascript
node.js操作MongoDB的实例详解
Oct 11 Javascript
angular将html代码输出为内容的实例
Sep 30 Javascript
Vue面试题及Vue知识点整理
Oct 07 Javascript
JS实现将对象转化为数组的方法分析
Jan 21 Javascript
jQuery 选择器用法实例分析【prev + next】
May 22 jQuery
JS实现audio音频剪裁剪切复制播放与上传(步骤详解)
Jul 28 Javascript
jquery的$().each和$.each的区别
Jan 18 #jQuery
使用form-create动态生成vue自定义组件和嵌套表单组件
Jan 18 #Javascript
jquery层次选择器的介绍
Jan 18 #jQuery
js实现图片放大并跟随鼠标移动特效
Jan 18 #Javascript
vue.js的双向数据绑定Object.defineProperty方法的神奇之处
Jan 18 #Javascript
jQuery无冲突模式详解
Jan 17 #jQuery
JQuery判断radio单选框是否选中并获取值的方法
Jan 17 #jQuery
You might like
PHP中Session的概念
2006/10/09 PHP
支持数组的ADDSLASHES的php函数
2010/02/16 PHP
php !function_exists(&quot;T7FC56270E7A70FA81A5935B72EACBE29&quot;))代码解密
2011/01/07 PHP
PHP几个数学计算的内部函数学习整理
2011/08/06 PHP
PHP简单获取及判断提交来源的方法
2016/04/22 PHP
Laravel使用swoole实现websocket主动消息推送的方法介绍
2019/10/20 PHP
javascript下数值型比较难点说明
2010/06/07 Javascript
JQuery设置和去除disabled属性的5种方法总结
2013/05/16 Javascript
很棒的js选项卡切换效果
2016/07/15 Javascript
Bootstrap Modal遮罩弹出层(完整版)
2016/11/21 Javascript
Vue自定义指令介绍(2)
2016/12/08 Javascript
利用jQuery实现一个简单的表格上下翻页效果
2017/03/14 Javascript
AngularJS封装$http.post()实例详解
2017/05/06 Javascript
微信小程序使用map组件实现检索(定位位置)周边的POI功能示例
2019/01/23 Javascript
详解关于Vuex的action传入多个参数的问题
2019/02/22 Javascript
初试vue-cli使用HBuilderx打包app的坑
2019/07/17 Javascript
浅谈vue异步数据影响页面渲染
2019/10/29 Javascript
vue获取form表单的值示例
2019/10/29 Javascript
浅谈javascript如何获取文件后缀名
2020/08/07 Javascript
js回到页面指定位置的三种方式
2020/12/17 Javascript
从头学Python之编写可执行的.py文件
2017/11/28 Python
PyTorch加载预训练模型实例(pretrained)
2020/01/17 Python
Python使用uuid库生成唯一标识ID
2020/02/12 Python
Python txt文件常用读写操作代码实例
2020/08/03 Python
详解Python中import机制
2020/09/11 Python
全球知名鞋履品牌授权零售商:Journeys
2016/09/17 全球购物
美国廉价机票预订网站:Cheapfaremart
2018/04/28 全球购物
六十大寿答谢词
2014/01/12 职场文书
2014信息公开实施方案
2014/02/22 职场文书
家长学校实施方案
2014/03/15 职场文书
《海伦?凯勒》教学反思
2014/04/17 职场文书
节约用水的口号
2014/06/20 职场文书
小学捐书活动总结
2014/07/05 职场文书
出租房屋协议书
2014/09/14 职场文书
护士长2014年度工作总结
2014/11/11 职场文书
MYSQL如何查看进程和kill进程
2022/03/13 MySQL