纯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 相关文章推荐
js 获取浏览器高度和宽度值(多浏览器)
Sep 02 Javascript
javascript 用记忆函数快速计算递归函数
Mar 15 Javascript
JS实现Enter键跳转及控件获得焦点
Aug 12 Javascript
简单的代码实现jquery定时器
Nov 17 Javascript
javascript实现微信分享
Dec 23 Javascript
利用Vue.js框架实现火车票查询系统(附源码)
Feb 27 Javascript
利用Jasmine对Angular进行单元测试的方法详解
Jun 12 Javascript
LayUi中接口传数据成功,表格不显示数据的解决方法
Aug 19 Javascript
react 应用多入口配置及实践总结
Oct 17 Javascript
微信小程序实现多选删除列表数据功能示例
Jan 15 Javascript
推荐一个基于Node.js的表单验证库
Feb 15 Javascript
Node.js 深度调试方法解析
Jul 28 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
php的list()的一步操作给一组变量进行赋值的使用
2011/05/18 PHP
PHP实现提高SESSION响应速度的几种方法详解
2019/08/09 PHP
IE/FireFox具备兼容性的拖动代码
2007/08/13 Javascript
Javascript在IE或Firefox下获取鼠标位置的代码
2009/12/18 Javascript
jquery 图片 上一张 下一张 链接效果(续篇)
2010/04/20 Javascript
javascript工厂方式定义对象
2014/12/26 Javascript
流量统计器如何鉴别C#:WebBrowser中伪造referer
2015/01/07 Javascript
JS与Ajax Get和Post在使用上的区别实例详解
2016/06/08 Javascript
Angular 2父子组件之间共享服务通信的实现
2017/07/04 Javascript
Vue注册组件命名时不能用大写的原因浅析
2019/04/25 Javascript
使用layer.msg 时间设置不起作用的解决方法
2019/09/12 Javascript
Nuxt配置Element-UI按需引入的操作方法
2020/07/06 Javascript
VUE项目实现主题切换的多种方法
2020/11/26 Vue.js
[01:21]DOTA2周边文化主题展 神秘商店火热开售
2017/07/30 DOTA
[48:46]完美世界DOTA2联赛PWL S2 SZ vs FTD.C 第二场 11.19
2020/11/19 DOTA
Java中重定向输出流实现用文件记录程序日志
2015/06/12 Python
python实现发送和获取手机短信验证码
2016/01/15 Python
Python使用arrow库优雅地处理时间数据详解
2017/10/10 Python
Python操作mongodb的9个步骤
2018/06/04 Python
Pandas 按索引合并数据集的方法
2018/11/15 Python
Python设计模式之享元模式原理与用法实例分析
2019/01/11 Python
基于Python实现迪杰斯特拉和弗洛伊德算法
2020/05/27 Python
python 通过可变参数计算n个数的乘积方法
2019/06/13 Python
Python3 合并二叉树的实现
2019/09/30 Python
解决os.path.isdir() 判断文件夹却返回false的问题
2019/11/29 Python
你应该知道的Python3.6、3.7、3.8新特性小结
2020/05/12 Python
pycharm设置默认的UTF-8编码模式的方法详解
2020/06/01 Python
简单了解Django项目应用创建过程
2020/07/06 Python
详解H5 活动页之移动端 REM 布局适配方法
2017/12/07 HTML / CSS
LORAC官网:美国彩妆品牌
2019/08/27 全球购物
Yankee Candle官网:美国最畅销蜡烛品牌之一
2020/01/05 全球购物
联想C++笔试题
2012/06/13 面试题
高中生毕业自我鉴定
2013/10/10 职场文书
亚运会口号
2014/06/20 职场文书
单位证明范文
2015/06/18 职场文书
CSS3点击按钮圆形进度打钩效果的实现代码
2021/03/30 HTML / CSS