纯javascript实现的小游戏《Flappy Pig》实例


Posted in Javascript onJuly 27, 2015

本文实例讲述了纯javascript实现的小游戏《Flappy Pig》。分享给大家供大家参考。具体如下:

Flappy Pig,是Pig,使用原生javascript写的网页版“Flappy Bird”。我也奇了个怪为什么搞这个东西出来,而且还花了一天宝贵的周末,但是既然写出来,就拿出来和大家分享一下。

option.js如下:

/**
 * 原生javascript实现的《Flappy Pig》v0.1.0
 * =======================================
 * @author keenwon
 * Full source at http://keenwon.com
 */
var flappy = (function (self) {
  'use strict';
  //设置
  self.option = {
    //重力加速度,屏幕像素和实际物理上的米有差别,所以存在换算
    g: 400,
    //跳跃的初速度,控制猪的弹跳力
    v0: 400,
    //柱子移动速度
    vp: 2.5,
    //频率,控制动画帧数,默认20ms
    frequency: 20,
    //关卡数
    levels: 100,
    //开头的空白距离
    safeLift: 500,
    //地板高度(和图片有关)
    floorHeight: 64,
    //猪的宽度
    pigWidth: 33,
    //猪的高度
    pigHeight: 30,
    //猪当前高度
    pigY: 300,
    //猪距离左边的距离,
    pigLeft: 80,
    //柱子Html
    pillarHtml: '<div class="top"></div><div class="bottom"></div>',
    //柱子宽度
    pillarWidth: 45,
    //柱子上下间隔高度
    pillarGapY: 108,
    //柱子左右间隔宽度
    pillarGapX: 250,
    //上柱子的基础定位值(就是top值,和css写法有关)
    pillarTop: -550,
    //下柱子的基础定位值
    pillarBottom: -500
  };
  return self;
})(flappy || {})

util.js如下:

/**
 * 原生javascript实现的《Flappy Pig》v0.1.0
 * =======================================
 * @author keenwon
 * Full source at http://keenwon.com
 */
var flappy = (function (self) {
  'use strict';
  //工具
  self.util = {
    preventDefaultEvent: function (event) {
      event = window.event || event;
      if (event) {
        if (event.preventDefault) {
          event.preventDefault();
        } else {
          event.returnValue = false;
        }
      }
    },
    $: function (id) {
      return document.getElementById(id);
    },
    getChilds: function (obj) {
      var childs = obj.children || obj.childNodes,
        childsArray = new Array();
      for (var i = 0, len = childs.length; i < len; i++) {
        if (childs[i].nodeType == 1) {
          childsArray.push(childs[i]);
        }
      }
      return childsArray;
    }
  };
  return self;
})(flappy || {})

pig.js如下:

/**
 * 原生javascript实现的《Flappy Pig》v0.1.0
 * =======================================
 * @author keenwon
 * Full source at http://keenwon.com
 */
var flappy = (function (self) {
  'use strict';
  var option = self.option,
    $ = self.util.$;
  //猪
  self.pig = {
    Y: 0, //猪当前高度(底边)
    init: function (overCallback, controller) {
      var t = this;
      t.s = 0, //位移
      t.time = 0, //时间
      t.$pig = $('pig');
      t.$pig.style.left = option.pigLeft + 'px';
      t._controller = controller;
      t._addListener(overCallback);
    },
    //添加监听
    _addListener: function (overCallback) {
      this._overCallback = overCallback;
    },
    //启动
    start: function () {
      var t = this,
        interval = option.frequency / 1000;
      t.s = option.v0 * t.time - t.time * t.time * option.g * 2; //竖直上抛运动公式
      t.Y = option.pigY + t.s;
      if (t.Y >= option.floorHeight) {
        t.$pig.style.bottom = t.Y + 'px';
      } else {
        t._dead();
      }
      t.time += interval;
    },
    //跳
    jump: function () {
      var t = this;
      option.pigY = parseInt(t.$pig.style.bottom);
      t.s = 0;
      t.time = 0;
    },
    //撞到地面时触发
    _dead: function () {
      this._overCallback.call(this._controller);
    },
    //撞到地面的处理
    fall: function () {
      var t = this;
      //摔到地上,修正高度
      t.Y = option.floorHeight;
      t.$pig.style.bottom = t.Y + 'px';
    },
    //撞到柱子的处理
    hit: function () {
      var t = this;
      //坠落
      var timer = setInterval(function () {
        t.$pig.style.bottom = t.Y + 'px';
        if (t.Y <= option.floorHeight) {
          clearInterval(timer);
        }
        t.Y -= 12;
      }, option.frequency);
    }
  };
  return self;
})(flappy || {})

pillar.js如下:

/**
 * 原生javascript实现的《Flappy Pig》v0.1.0
 * =======================================
 * @author keenwon
 * Full source at http://keenwon.com
 */
var flappy = (function (self) {
  'use strict';
  var option = self.option,
    util = self.util,
    $ = util.$;
  //柱子
  self.pillar = {
    currentId: -1, //当前柱子id
    init: function () {
      var t = this;
      //缓存上下柱子位置的换算因子
      t._factor = option.pillarBottom - option.pillarGapY + 450;
      //s表示一个位置,到达这个位置的柱子就是“当前的柱子”,就算是靠近猪了,开始计算猪有没有撞到这根柱子,10是提前量。
      t._s = option.pigLeft + option.pigWidth + 10;
      t._render();
    },
    //把柱子渲染到DOM树中
    _render: function () {
      var t = this,
        initleft = option.safeLift;
      t.left = 0;
      t.dom = document.createElement('div');
      t.dom.className = t.dom.id = 'pillarWrapper';
      for (var i = 0, j = option.levels; i < j; i++) {
        var el = document.createElement('div');
        el.innerHTML = option.pillarHtml;
        el.className = 'pillar';
        el.id = 'pillar-' + i;
        el.style.left = initleft + 'px';
        var childs = util.getChilds(el),
          topEl = childs[0],
          bottomEl = childs[1],
          pos = t._random(i);
        topEl.style.top = pos.top + 'px';
        bottomEl.style.bottom = pos.bottom + 'px';
        el.setAttribute('top', 600 + pos.top);
        el.setAttribute('bottom', 0 - pos.bottom);
        t.dom.appendChild(el);
        initleft += option.pillarGapX;
      }
      $('screen').appendChild(t.dom);
    },
    //计算柱子位置
    _random: function (i) {
      var t = this,
        x = Math.random(),
        h = Math.abs(Math.sin((i+1) * x)) * 290;
      return {
        top: option.pillarTop + h,
        bottom: t._factor - h
      }
    },
    //移动柱子
    move: function () {
      var t = this;
      t.dom.style.left = -t.left + 'px';
      t._find(t.left);
      t.left += option.vp;
    },
    //找到当前的柱子
    _find: function (l) {
      var t = this,
        x = (t._s + l - option.safeLift) / option.pillarGapX,
        intX = parseInt(x); //intX是当前柱子
      if (x > 0 && t.currentId != intX && Math.abs(x - intX) < 0.1) {
        t.currentId = intX;
      }
    }
  };
  return self;
})(flappy || {})

position.js如下:

/**
 * 原生javascript实现的《Flappy Pig》v0.1.0
 * =======================================
 * @author keenwon
 * Full source at http://keenwon.com
 */
var flappy = (function (self) {
  'use strict';
  var pig = self.pig,
    pillar = self.pillar,
    option = self.option,
    $ = self.util.$;
  //位置判断
  self.position = {
    init: function (overCallback, controller) {
      var t = this;
      t.pillarWrapper = $('pillarWrapper');
      t.pigX1 = option.pigLeft,
      t.pigX2 = option.pigLeft + option.pigWidth, //猪的左右位置,固定的
      t._controller = controller;
      t._addListener(overCallback);
    },
    //添加监听
    _addListener: function (overCallback) {
      this._overCallback = overCallback;
    },
    judge: function () {
      var t = this,
        currentPillar = $('pillar-' + pillar.currentId);
      if (pillar.currentId == -1) {
        return;
      }
      t.pigY2 = 600 - pig.Y;
      t.pigY1 = t.pigY2 - option.pigHeight; //猪的上下位置
      t.pY1 = currentPillar.getAttribute('top');
      t.pY2 = currentPillar.getAttribute('bottom');
      t.pX1 = parseInt(currentPillar.style.left) + parseInt(t.pillarWrapper.style.left);
      t.pX2 = t.pX1 + option.pillarWidth; //柱子的上下左右位置
      console.log(t.pillarWrapper.style.left);
      if (option.pigLeft + option.pigWidth >= t.pX1 && option.pigLeft <= t.pX2) {
        if (t.pigY1 < t.pY1 || t.pigY2 > t.pY2) {
          t._dead();
        }
      }
    },
    //撞到柱子时触发
    _dead: function () {
      this._overCallback.call(this._controller);
    },
  };
  return self;
})(flappy || {})

controller.js如下:

/**
 * 原生javascript实现的《Flappy Pig》v0.1.0
 * =======================================
 * @author keenwon
 * Full source at http://keenwon.com
 */
var flappy = (function (self) {
  'use strict';
  var pig = self.pig,
    pillar = self.pillar,
    pos = self.position,
    util = self.util,
    $ = util.$,
    option = self.option;
  //控制器
  self.controller = {
    init: function () {
      var t = this;
      t._isStart = false;
      t._timer = null;
      pig.init(t.fall, t);
      pillar.init();
      pos.init(t.hit, t);
      t.addKeyListener();
    },
    addKeyListener: function () {
      var t = this;
      document.onkeydown = function (e) {
        var e = e || event;
        var currKey = e.keyCode || e.which || e.charCode;
        if (currKey == 32) {
          t.jump();
          util.preventDefaultEvent(e);
        }
      }
    },
    jump: function () {
      var t = this;
      if (!t._isStart) {
        $('begin').style.display = 'none';
        t._createTimer(function () {
          pig.start();
          pillar.move();
          pos.judge();
          $('score').innerHTML = pillar.currentId + 1;
        });
        t._isStart = true;
      } else {
        pig.jump();
      }
    },
    hit: function () {
      var t = this;
      t.over();
      pig.hit();
    },
    fall: function () {
      var t = this;
      t.over();
      pig.fall();
    },
    over: function () {
      var t = this;
      clearInterval(t._timer);
      $('end').style.display = 'block';
    },
    _createTimer: function (fn) {
      var t = this;
      t._timer = setInterval(fn, option.frequency);
    }
  };
  return self;
})(flappy || {})

game.js如下:

/**
 * 原生javascript实现的《Flappy Pig》v0.1.0
 * =======================================
 * @author keenwon
 * Full source at http://keenwon.com
 */
var flappy = (function (self) {
  'use strict';
  var controller = self.controller,
    option = self.option,
    pig = self.pig,
    pillar = self.pillar,
    pos = self.position,
    util = self.util,
    $ = self.util.$;
  //主程序
  self.game = {
    init: function () {
      var t = this;
      t._isStart = false;
      t._isEnd = false;
      t._timer = null;
      pig.init(t.fall, t);
      pillar.init();
      pos.init(t.hit, t);
      t.addKeyListener();
    },
    addKeyListener: function () {
      var t = this;
      document.onkeydown = function (e) {
        var e = e || event;
        var currKey = e.keyCode || e.which || e.charCode;
        if (currKey == 32) {
          if (!t._isEnd) {
            t.jump();
          } else {
            window.location.reload();
          }
          util.preventDefaultEvent(e);
        }
      }
    },
    jump: function () {
      var t = this;
      if (!t._isStart) {
        $('start').style.display = 'none';
        t._createTimer(function () {
          pig.start();
          pillar.move();
          pos.judge();
          $('score').innerHTML = pillar.currentId + 1;
        });
        t._isStart = true;
      } else {
        pig.jump();
      }
    },
    hit: function () {
      var t = this;
      t.over();
      pig.hit();
    },
    fall: function () {
      var t = this;
      t.over();
      pig.fall();
    },
    over: function () {
      var t = this;
      clearInterval(t._timer);
      t._isEnd = true;
      $('end').style.display = 'block';
    },
    _createTimer: function (fn) {
      var t = this;
      t._timer = setInterval(fn, option.frequency);
    }
  };
  flappy.init = function () {
    self.game.init();
  }
  return self;
})(flappy || {})

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

Javascript 相关文章推荐
ext for eclipse插件安装方法
Apr 27 Javascript
jquery ajax修改全局变量示例代码
Nov 08 Javascript
浅谈javascript 归并方法
Jan 21 Javascript
详解JavaScript中的客户端消息框架设计原理
Jun 24 Javascript
jQuery检测返回值的数据类型
Jul 13 Javascript
JS创建事件的三种方法(实例代码)
May 12 Javascript
深入解析桶排序算法及Node.js上JavaScript的代码实现
Jul 06 Javascript
gulp加批处理(.bat)实现ng多应用一键自动化构建
Feb 16 Javascript
基于 Bootstrap Datetimepicker 联动
Aug 03 Javascript
Vue 动态设置路由参数的案例分析
Apr 24 Javascript
vue生成token并保存到本地存储中
Jul 17 Javascript
JavaScript实现的文本框placeholder提示文字功能示例
Jul 25 Javascript
JavaScript中利用Array和Object实现Map的方法
Jul 27 #Javascript
JavaScript数据库TaffyDB用法实例分析
Jul 27 #Javascript
javascript简单实现滑动菜单效果的方法
Jul 27 #Javascript
JavaScript判断IE版本型号
Jul 27 #Javascript
javascript通过获取html标签属性class实现多选项卡的方法
Jul 27 #Javascript
readonly和disabled属性的区别
Jul 26 #Javascript
javascript实现继承的简单实例
Jul 26 #Javascript
You might like
fleaphp常用方法分页之Pager使用方法
2011/04/23 PHP
simplehtmldom Doc api帮助文档
2012/03/26 PHP
关于PHP结束标签的使用细节探讨及联想
2013/03/04 PHP
PHP中加密解密函数与DES加密解密实例
2014/10/17 PHP
使用XHGui来测试PHP性能的教程
2015/07/03 PHP
PHP函数引用返回的实例详解
2016/09/11 PHP
PHP实现求两个字符串最长公共子串的方法示例
2017/11/17 PHP
jquery与js函数冲突的两种解决方法
2013/09/09 Javascript
JS 日期比较大小的简单实例
2014/01/13 Javascript
angularjs中的单元测试实例
2014/12/06 Javascript
介绍JavaScript中Math.abs()方法的使用
2015/06/14 Javascript
Jquery左右滑动插件之实现超级炫酷动画效果附源码下载
2015/12/02 Javascript
BootStrap.css 在手机端滑动时右侧出现空白的原因及解决办法
2016/06/07 Javascript
jquery中关于bind()方法的使用技巧分享
2017/03/30 jQuery
vue 打包后的文件部署到express服务器上的方法
2017/08/09 Javascript
基于VUE移动音乐WEBAPP跨域请求失败的解决方法
2018/01/16 Javascript
vue中vee validate表单校验的几种基本使用
2018/06/25 Javascript
vue + axios get下载文件功能
2019/09/25 Javascript
Bootstrap FileInput实现图片上传功能
2021/01/28 Javascript
Python提示[Errno 32]Broken pipe导致线程crash错误解决方法
2014/11/19 Python
使用Python求解最大公约数的实现方法
2015/08/20 Python
Python中列表和元组的使用方法和区别详解
2020/12/30 Python
Python创建xml文件示例
2017/03/22 Python
Python使用PIL模块生成随机验证码
2017/11/21 Python
解决pycharm 远程调试 上传 helpers 卡住的问题
2019/06/27 Python
kafka监控获取指定topic的消息总量示例
2019/12/23 Python
通过实例了解Python str()和repr()的区别
2020/01/17 Python
整个世界的设计师家具在哈恩:Designathome
2019/03/25 全球购物
日常奢侈品,轻松购物:Verishop
2019/08/20 全球购物
高校毕业生登记表自我鉴定
2013/11/03 职场文书
军训 自我鉴定
2014/02/03 职场文书
促销活动总结模板
2014/07/01 职场文书
秋季运动会广播稿(30篇)
2014/09/13 职场文书
红色经典观后感
2015/06/18 职场文书
导游词之阆中古城
2019/12/23 职场文书
CSS 新特性 contain控制页面的重绘与重排问题
2021/04/30 HTML / CSS