原生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 相关文章推荐
jQuery判断checkbox(复选框)是否被选中以及全选、反选实现代码
Feb 21 Javascript
jQuery实现放大镜效果实例代码
Mar 17 Javascript
基于MVC5和Bootstrap的jQuery TreeView树形控件(二)之数据支持json字符串、list集合
Aug 11 Javascript
AngularJs基于角色的前端访问控制的实现
Nov 07 Javascript
微信小程序学习之数据处理详解
Jul 05 Javascript
基于Two.js实现星球环绕动画效果的示例
Nov 06 Javascript
nginx+vue.js实现前后端分离的示例代码
Feb 12 Javascript
vue select选择框数据变化监听方法
Aug 24 Javascript
JavaScript 斐波那契数列 倒序输出 输出100以内的质数代码实例
Sep 11 Javascript
使用webpack将ES6转化ES5的实现方法
Oct 13 Javascript
JavaScript动画实例之粒子文本的实现方法详解
Jul 28 Javascript
JavaScript canvas实现雨滴特效
Jan 10 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
php 执行系统命令的方法
2009/07/07 PHP
PHP-redis中文文档介绍
2013/02/07 PHP
PHP+JQuery+Ajax实现分页方法详解
2016/08/06 PHP
PHP PDOStatement::nextRowset讲解
2019/02/01 PHP
Yii框架实现对数据库的CURD操作示例
2019/09/03 PHP
Nigma vs AM BO3 第二场2.13
2021/03/10 DOTA
CutePsWheel javascript libary 控制输入文本框为可使用滚轮控制的js库
2010/02/07 Javascript
js插件方式打开pdf文件(浏览器pdf插件分享)
2013/12/20 Javascript
node.js中的fs.rmdir方法使用说明
2014/12/16 Javascript
jQuery+jsp实现省市县三级联动效果(附源码)
2015/12/03 Javascript
js闭包引起的事件注册问题介绍
2016/03/29 Javascript
xmlplus组件设计系列之按钮(2)
2017/04/26 Javascript
JS常用正则表达式总结【经典】
2017/05/12 Javascript
利用Three.js如何实现阴影效果实例代码
2017/09/26 Javascript
JS实现字符串中去除指定子字符串方法分析
2018/05/17 Javascript
JS使用JSON.parse(),JSON.stringify()实现对对象的深拷贝功能分析
2019/03/06 Javascript
解决vue 单文件组件中样式加载问题
2019/04/24 Javascript
基于JS实现数字动态变化显示效果附源码
2019/07/18 Javascript
vue中使用[provide/inject]实现页面reload的方法
2019/09/30 Javascript
vue中keep-alive、activated的探讨和使用详解
2020/07/26 Javascript
JS图片懒加载技术实现过程解析
2020/07/27 Javascript
VUE UPLOAD 通过ACTION返回上传结果操作
2020/09/07 Javascript
[00:06]Yes,it worked!小卡尔成功穿越时空加入战场!
2019/07/20 DOTA
Python赋值语句后逗号的作用分析
2015/06/08 Python
python实现复制文件到指定目录
2019/10/16 Python
大四毕业生学习总结的自我评价
2013/10/31 职场文书
机电一体化应届生求职信范文
2014/01/24 职场文书
申请任职学生会干部自荐书范文
2014/02/13 职场文书
2014年乡镇领导个人整改措施
2014/09/19 职场文书
家庭财产分割协议书范本
2014/11/24 职场文书
2015商场元旦促销活动策划方案
2014/12/09 职场文书
毕业班工作总结
2015/08/10 职场文书
2016反腐倡廉警示教育心得体会
2016/01/13 职场文书
JavaScript组合继承详解
2021/11/07 Javascript
浅析python中特殊文件和特殊函数
2022/02/24 Python
用Python仅20行代码编写一个简单的端口扫描器
2022/04/08 Python