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 相关文章推荐
jquery实现对联广告的方法
Feb 05 Javascript
jquery实现表格隔行换色效果
Nov 19 Javascript
js调出上下文菜单的实例
Dec 17 Javascript
jQuery实现的自定义弹出层效果实例详解
Sep 04 Javascript
深入理解javascript中的 “this”
Jan 17 Javascript
Vue中引入样式文件的方法
Aug 18 Javascript
Angular浏览器插件Batarang介绍及使用
Feb 07 Javascript
jquery实现选项卡切换代码实例
May 14 jQuery
JsonServer安装及启动过程图解
Feb 28 Javascript
vant中的toast轻提示实现代码
Nov 04 Javascript
JS使用setInterval计时器实现挑战10秒
Nov 08 Javascript
在HTML中使用JavaScript的两种方法
Dec 24 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 iconv 解决utf-8和gb2312编码转换问题
2010/04/12 PHP
ThinkPHP结合ajax、Mysql实现的客户端通信功能代码示例
2014/06/23 PHP
编写PHP脚本清除WordPress头部冗余代码的方法讲解
2016/03/01 PHP
PHP+Ajax实现的无刷新分页功能详解【附demo源码下载】
2017/07/03 PHP
PHP中in_array的隐式转换的解决方法
2018/03/06 PHP
PHP asXML()函数讲解
2019/02/03 PHP
分享精心挑选的23款美轮美奂的jQuery 图片特效插件
2012/08/14 Javascript
JS冒泡事件的快速解决方法
2013/12/16 Javascript
javascript轻松实现当鼠标移开时已弹出子菜单自动消失
2013/12/29 Javascript
快速解决jquery.touchSwipe左右滑动和垂直滚动条冲突
2016/04/15 Javascript
JS中dom0级事件和dom2级事件的区别介绍
2016/05/05 Javascript
js实现做通讯录的索引滑动显示效果和滑动显示锚点效果
2017/02/18 Javascript
Vue上传组件vue Simple Uploader的用法示例
2017/08/25 Javascript
详解tween.js的使用教程
2017/09/14 Javascript
Node.js学习之地址解析模块URL的使用详解
2017/09/28 Javascript
浅谈Node.js CVE-2017-14849 漏洞分析(详细步骤)
2017/11/10 Javascript
promise和co搭配生成器函数方式解决js代码异步流程的比较
2018/05/25 Javascript
Rollup处理并打包JS文件项目实例代码
2018/05/31 Javascript
vue2.0$nextTick监听数据渲染完成之后的回调函数方法
2018/09/11 Javascript
如何在微信小程序中实现Mixins方案
2019/06/20 Javascript
JS实现京东商品分类侧边栏
2020/12/11 Javascript
在Django的模型中添加自定义方法的示例
2015/07/21 Python
Python 专题一 函数的基础知识
2017/03/16 Python
Python实现自定义函数的5种常见形式分析
2018/06/16 Python
python实现列表中由数值查到索引的方法
2018/06/27 Python
Python实现注册、登录小程序功能
2018/09/21 Python
关于Pytorch的MNIST数据集的预处理详解
2020/01/10 Python
Python连接mysql数据库及简单增删改查操作示例代码
2020/08/03 Python
通俗易懂了解Python装饰器原理
2020/09/17 Python
Python实现我的世界小游戏源代码
2021/03/02 Python
美国婚戒购物网站:Anjays Designs
2017/06/28 全球购物
速比涛英国官网:Speedo英国
2019/07/15 全球购物
Gerry Weber德国官网:优质女性时装,德国最大的时装公司之一
2019/11/02 全球购物
冬季作息时间调整通知
2015/04/24 职场文书
公司处罚决定书
2015/06/24 职场文书
24年收藏2000多部退役军用电台
2022/02/18 无线电