纯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控制div及网页相关属性的代码
Dec 19 Javascript
Lazy Load 延迟加载图片的 jQuery 插件
Feb 06 Javascript
JS+CSS实现可以凹陷显示选中单元格的方法
Mar 02 Javascript
js阻止浏览器默认行为触发的通用方法(推荐)
May 15 Javascript
为什么JavaScript没有块级作用域
May 22 Javascript
微信小程序  生命周期详解
Oct 27 Javascript
canvas知识总结
Jan 25 Javascript
angular之ng-template模板加载
Nov 09 Javascript
详解vue静态资源打包中的坑与解决方案
Feb 05 Javascript
Vue源码学习之关于对Array的数据侦听实现
Apr 23 Javascript
搭建一个Koa后端项目脚手架的方法步骤
May 30 Javascript
vue实现随机验证码功能(完整代码)
Dec 10 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查询MySQL大量数据的时候内存占用分析
2011/07/22 PHP
PHP创建单例后台进程的方法示例
2017/05/23 PHP
php JWT在web端中的使用方法教程
2018/09/06 PHP
jquery下异步提交表单 异步跨域提交表单
2010/11/17 Javascript
超轻量级的基于jquery的三级展开列表
2011/04/26 Javascript
jQuery 在光标定位的地方插入文字的插件
2012/05/10 Javascript
jquery remove方法应用详解
2012/11/22 Javascript
关于JQuery($.load)事件的用法和分析
2013/04/09 Javascript
jQuery - css() 方法示例详解
2014/01/16 Javascript
jquery基础教程之deferred对象使用方法
2014/01/22 Javascript
js 模式窗口(模式对话框和非模式对话框)的使用介绍
2014/07/17 Javascript
javascript实用方法总结
2015/02/06 Javascript
javascript实现点击按钮让DIV层弹性移动的方法
2015/02/24 Javascript
Bootstrap CSS组件之导航条(navbar)
2016/12/17 Javascript
jQuery插件FusionCharts实现的MSBar3D图效果示例【附demo源码】
2017/03/23 jQuery
jQuery中库的引用方法
2018/01/06 jQuery
vue router+vuex实现首页登录验证判断逻辑
2018/05/17 Javascript
Vue开发实现吸顶效果的示例代码
2018/08/21 Javascript
解决vue 格式化银行卡(信用卡)每4位一个符号隔断的问题
2018/09/14 Javascript
three.js实现圆柱体
2018/12/30 Javascript
uploadify插件实现多个图片上传并预览
2019/09/30 Javascript
详解vue页面首次加载缓慢原因及解决方案
2019/11/06 Javascript
Javascript中的this,bind和that使用实例
2019/12/05 Javascript
Openlayers显示瓦片网格信息的方法
2020/09/28 Javascript
python简单获取本机计算机名和IP地址的方法
2015/06/03 Python
python 3.6.4 安装配置方法图文教程
2018/09/18 Python
Python socket实现多对多全双工通信的方法
2019/02/13 Python
Python面向对象程序设计之类的定义与继承简单示例
2019/03/18 Python
解决pycharm remote deployment 配置的问题
2019/06/27 Python
django 数据库连接模块解析及简单长连接改造方法
2019/08/29 Python
python爬虫scrapy基本使用超详细教程
2021/02/20 Python
美国当红的名品折扣网:Gilt Groupe
2016/08/15 全球购物
BRASTY捷克:购买香水、化妆品、手袋和手表
2017/07/12 全球购物
美德少年事迹材料
2014/01/23 职场文书
病危通知单
2015/04/17 职场文书
HTML怎么设置下划线?html文字加下划线方法
2021/12/06 HTML / CSS