原生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 相关文章推荐
限制文本字节数js代码
Mar 06 Javascript
js操作Xml(向服务器发送Xml,处理服务器返回的Xml)(IE下有效)
Jan 30 Javascript
javascript 对象比较实现代码
Apr 27 Javascript
jquery单行文字向上滚动效果示例
Mar 06 Javascript
跟我学习javascript的prototype使用注意事项
Nov 17 Javascript
分享javascript计算时间差的示例代码
Mar 19 Javascript
node.js Sequelize实现单实例字段或批量自增、自减
Dec 08 Javascript
浅述节点的创建及常见功能的实现
Dec 15 Javascript
详解Angular2响应式表单
Jun 14 Javascript
Windows安装Node.js报错:2503、2502的解决方法
Oct 25 Javascript
Vue2.X和Vue3.0数据响应原理变化的区别
Nov 07 Javascript
原生JS实现相邻月份日历
Oct 13 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
多文件上载系统完整版
2006/10/09 PHP
JS IE和FF兼容性问题汇总
2009/02/09 Javascript
基于jQuery+HttpHandler实现图片裁剪效果代码(适用于论坛, SNS)
2011/09/02 Javascript
json中换行符的处理方法示例介绍
2014/06/10 Javascript
IE6-IE9中tbody的innerHTML不能赋值的解决方法
2014/09/26 Javascript
Javascript基础_嵌入图像的简单实现
2016/06/14 Javascript
jQuery实现的瀑布流加载效果示例
2016/09/13 Javascript
javascript中异常处理案例(推荐)
2016/10/03 Javascript
Vue.js一个文件对应一个组件实践
2016/10/27 Javascript
vue双向绑定的简单实现
2016/12/22 Javascript
JS实现汉字与Unicode码相互转换的方法详解
2017/04/28 Javascript
详解Vue2.0 事件派发与接收
2017/09/05 Javascript
webpack+vue-cli项目中引入外部非模块格式js的方法
2018/09/28 Javascript
Vuex持久化插件(vuex-persistedstate)解决刷新数据消失的问题
2019/04/16 Javascript
浅谈webpack 四个核心概念之Entry
2019/06/12 Javascript
基于vue的tab-list类目切换商品列表组件的示例代码
2020/02/14 Javascript
[01:03:36]Ti4 循环赛第三日DK vs Titan
2014/07/12 DOTA
使用python实现baidu hi自动登录的代码
2013/02/10 Python
Python with用法实例
2015/04/14 Python
python实现爬虫统计学校BBS男女比例之数据处理(三)
2015/12/31 Python
Python实现求两个csv文件交集的方法
2017/09/06 Python
Spring实战之使用util:命名空间简化配置操作示例
2019/12/09 Python
django 前端页面如何实现显示前N条数据
2020/03/16 Python
Python如何实现自带HTTP文件传输服务
2020/07/08 Python
详解Html5原生拖拽操作
2018/01/12 HTML / CSS
Aveda美国官网:天然护发产品、洗发水、护发素和沙龙
2016/12/09 全球购物
Jacadi Paris美国官方网站:法国童装品牌
2017/10/15 全球购物
项目总经理岗位职责
2014/02/14 职场文书
40岁生日感言
2014/02/15 职场文书
装修设计师求职信
2014/02/26 职场文书
出纳员岗位职责风险
2014/03/06 职场文书
《明天,我们毕业》教学反思
2014/04/24 职场文书
产品质量保证书范本
2015/02/27 职场文书
结婚司仪主持词
2015/06/29 职场文书
2019年圣诞节祝福语集锦
2019/12/25 职场文书
Python使用psutil库对系统数据进行采集监控的方法
2021/08/23 Python