原生js实现Flappy Bird小游戏


Posted in Javascript onDecember 24, 2018

这是一个特别简单的用原生js实现的一个小鸟游戏,比较简单,适合新手练习。

原生js实现Flappy Bird小游戏

html结构

<div id="game">
  <div id="bird"></div>
</div>

css样式

#game {
    width: 800px;
    height: 600px;
    border: 1px solid #000;
    background: url(images/sky.png);
    overflow: hidden;
    position: relative;
  }

  #game .pipeD {
    background: url(images/pipe1.png) top center;
    position: absolute;
  }

  #game .pipeU {
    background: url(images/pipe2.png) bottom center;
    position: absolute;
  }

  #bird {
    width: 34px;
    height: 25px;
    /*border-radius: 10px;*/
    /*background-color: red;*/
    position: absolute;
    top: 100px;
    left: 100px;
    background: url(images/birds.png) -8px -10px no-repeat;
  }

下面就是原生js代码了,这个小案例还运用了自己前期封装的一个小的动画方法

function animate(obj, json, fn) {
  clearInterval(obj.timer);
  obj.timer = setInterval(function () {
    var flag = true;
    for (var k in json) {
      if (k === "opacity") {
        var leader = getStyle(obj, k) * 100;
        var target = json[k] * 100;
        var step = (target - leader) / 10;
        step = step > 0 ? Math.ceil(step) : Math.floor(step);
        leader = leader + step;
        obj.style[k] = leader / 100;
      } else if (k === "zIndex") {
        obj.style.zIndex = json[k];
      } else {
        var leader = parseInt(getStyle(obj, k)) || 0;
        var target = json[k];
        var step = (target - leader) / 10;
        step = step > 0 ? Math.ceil(step) : Math.floor(step);
        leader = leader + step;
        obj.style[k] = leader + "px";
      }
      if (leader !== target) {
        flag = false;
      }
    }
    if (flag) {
      clearInterval(obj.timer);
      if (fn) {
        fn();
      }
    }
  }, 15);
}
function getStyle(obj, attr) {
  if (window.getComputedStyle) {
    return window.getComputedStyle(obj)[attr];
  } else {
    return obj.currentStyle[attr];
  }
}

下面就是控制游戏的js代码了

var birdElement = document.getElementById("bird");
var game = document.getElementById("game");
var gameover = false;
var g = 1;
var i = 0;
var timer=null;
var bird = {
  x: birdElement.offsetLeft,
  y: birdElement.offsetTop,
  speedX: 5,
  speedY: 0,
  entity: birdElement
};
var sky = {
  x: 0
};

//var timer=setInterval(function(){
//  birdElement.style.backgroundPositionX=-52*i+"px";
//  i++;
//  if(i===3){
//    i=0;
//  }
//},100);

setInterval(function () {
  //游戏没有结束的时候运行代码
  if (!gameover) {
    //整个游戏背景x轴移动的距离
    sky.x = sky.x - bird.speedX;
    game.style.backgroundPositionX = sky.x + "px";
    //小鸟下落时y轴的坐标
    bird.speedY = bird.speedY + g;
    //设置一个变量用来接收小鸟下落时y轴的坐标,用来设置小鸟下降时的速度
    var step = bird.speedY;
    bird.y = bird.y + step;
    //用一个变量来设定小鸟下落的最低高度,用来 判断游戏是否结束
    var overY = game.offsetHeight - birdElement.offsetHeight;
    //小鸟的y轴坐标大于最低高度,所以游戏停止
    if (bird.y > overY) {
      bird.y = overY;
      stop();
    }
    //小鸟的y轴坐标小于0,说明碰到顶部边框,所以游戏结束
    if (bird.y < 0) {
      bird.y = 0;
      stop();
    }
    //设置游戏开始时小鸟出现的位置
    bird.entity.style.top = bird.y + "px";
  }
}, 25);
//添加键盘事件,实现键盘上下键控制小鸟
document.onkeyup = function (e) {
  if (e.keyCode === 38) {
    bird.speedY = -10;
  }
}

function Pipe(positonX) {
  //管子的坐标
  this.x = positonX;
  this.upPipeY = 0;
  this.width = 52;
  this.upPipeH = parseInt(Math.random() * 175 + 100);
  this.downPipeY = this.upPipeH + 200;
  this.downPipeH = game.offsetHeight - this.downPipeY;
  // 动态添加管子
  var divUp = document.createElement("div");
  divUp.className = "pipeU";
  divUp.style.width = this.width + "px";
  divUp.style.height = this.upPipeH + "px";
  divUp.style.left = this.x + "px";
  divUp.style.top = this.upPipeY + "px";
  game.appendChild(divUp);
  var divDown = document.createElement("div");
  divDown.className = "pipeD";
  divDown.style.width = this.width + "px";
  divDown.style.height = this.downPipeH + "px";
  divDown.style.left = this.x + "px";
  divDown.style.top = this.downPipeY + "px";
  game.appendChild(divDown);
  //因为定时器会混乱this的指向问题,所以提前保存this的指向,这里的this指向调用该方法的实例
  var that = this;
  // 设置定时器让管子向后移动
  this.timer=setInterval(function () {
    that.x = that.x - 1;
    //简单实现管子无缝滚动
    if (that.x < -52) {
      that.x = 800;
    }
    if (!gameover) {
      divUp.style.left = that.x + "px";
      divDown.style.left = that.x + "px";
    }
    // 设置变量,进行游戏碰撞检测,并停止游戏
    var downCrash = (bird.x + 34 > that.x) && (bird.x < that.x + 52) && (bird.y + 25 > that.downPipeY);
    var upCrash = (bird.x + 34 > that.x) && (bird.x < that.x + 52) && (bird.y < that.upPipeH);
    if (downCrash || upCrash) {
      //gameover = true;
      stop();
    }
  }, 10);
}
//执行上面的函数方法
var arr=[];
for (var i = 0; i < 4; i++) {
  arr[i]=new Pipe(i * 200 + 400);
}
//封装一个用来停止游戏的方法,
function stop(){
  gameover=true;
  clearInterval(timer);
  for(var i=0;i<arr.length;i++){
    clearInterval(arr[i].timer);
  }
}

注释都写在了了代码里,一个简单小游戏就完成了。

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持三水点靠木。

Javascript 相关文章推荐
在线编辑器中换行与内容自动提取
Apr 24 Javascript
jQuery checkbox全选/取消全选实现代码
Nov 14 Javascript
JS使用getComputedStyle()方法获取CSS属性值
Apr 23 Javascript
ext combobox动态加载数据库数据(附前后台)
Jun 17 Javascript
直接在JS里创建JSON数据然后遍历使用
Jul 25 Javascript
JavaScript判断IE版本型号
Jul 27 Javascript
jQuery左右滚动支持图片放大缩略图图片轮播代码分享
Aug 26 Javascript
原生js实现秒表计时器功能
Feb 16 Javascript
关于jQuery中fade(),show()起始位置的一点小发现
Apr 25 jQuery
基于vue2.x的电商图片放大镜插件的使用
Jan 22 Javascript
使用ng-packagr打包Angular的方法示例
Sep 21 Javascript
js实现菜单跳转效果
Dec 11 Javascript
node错误处理与日志记录的实现
Dec 24 #Javascript
详解如何在vscode里面调试js和node.js的方法步骤
Dec 24 #Javascript
@angular前端项目代码优化之构建Api Tree的方法
Dec 24 #Javascript
微信小程序获取用户openid的实现
Dec 24 #Javascript
vue-router启用history模式下的开发及非根目录部署方法
Dec 23 #Javascript
小程序实现人脸识别功能(百度ai)
Dec 23 #Javascript
优雅的elementUI table单元格可编辑实现方法详解
Dec 23 #Javascript
You might like
jquery 操作表格实现代码(多种操作打包)
2011/03/20 Javascript
javascript延时加载之defer测试
2012/12/28 Javascript
js绑定事件this指向发生改变的问题解决方法
2013/04/23 Javascript
js判断浏览器类型的方法
2013/08/07 Javascript
jquery仿搜索自动联想功能代码
2014/05/23 Javascript
js闭包的用途详解
2014/11/09 Javascript
innerHTML属性,outerHTML属性,textContent属性,innerText属性区别详解
2015/03/13 Javascript
javascript操作ul中li的方法
2015/05/14 Javascript
JavaScript中setUTCFullYear()方法的使用简介
2015/06/12 Javascript
JavaScript如何调试有哪些建议和技巧附五款有用的调试工具
2015/10/28 Javascript
JavaScript方法_动力节点Java学院整理
2017/06/28 Javascript
JS数组操作中的经典算法实例讲解
2017/07/26 Javascript
AngularJs ng-change事件/指令的用法小结
2017/11/01 Javascript
JavaScript实现的DOM树遍历方法详解【二叉DOM树、多叉DOM树】
2018/05/07 Javascript
Webpack中雪碧图插件使用详解
2018/05/25 Javascript
vue router 配置路由的方法
2018/07/26 Javascript
vue内置组件component--通过is属性动态渲染组件操作
2020/07/28 Javascript
JavaScript实现多球运动效果
2020/09/07 Javascript
浅析微信小程序自定义日历组件及flex布局最后一行对齐问题
2020/10/29 Javascript
使用Python操作excel文件的实例代码
2017/10/15 Python
使用Python监控文件内容变化代码实例
2018/06/04 Python
python获取当前文件路径以及父文件路径的方法
2019/07/10 Python
从pandas一个单元格的字符串中提取字符串方式
2019/12/17 Python
Python 内置变量和函数的查看及说明介绍
2019/12/25 Python
pandas数据处理之绘图的实现
2020/06/15 Python
查看keras的默认backend实现方式
2020/06/19 Python
CSS3动画animation实现云彩向左滚动
2014/05/09 HTML / CSS
CSS3为背景图设置遮罩并解决遮罩样式继承问题
2020/06/22 HTML / CSS
毕业生机械建模求职信
2013/10/14 职场文书
八年级历史教学反思
2014/01/10 职场文书
学校元旦晚会方案
2014/02/19 职场文书
党员十八大心得体会
2014/09/12 职场文书
教师个人教学总结
2015/02/11 职场文书
销售助理岗位职责
2015/02/11 职场文书
分家协议书范本
2016/03/22 职场文书
Java实现多线程聊天室
2021/06/26 Java/Android