JavaScript实现Fly Bird小游戏


Posted in Javascript onDecember 15, 2016

本教程为大家分享了Fly Bird小游戏的制作流程,供大家参考,具体内容如下

1.分析页面结构,理清需求和功能

游戏有三个界面,分别是开始界面,游戏界面和游戏结束界面。

1.1 开始界面

JavaScript实现Fly Bird小游戏

start.gif

游戏的大背景
上下移动的游戏标题和翅膀摆动的小鸟
start 按钮,点击进入游戏界面
一直移动的地面

1.2 游戏界面

JavaScript实现Fly Bird小游戏

play.gif

显示越过障碍数量的计分器
移动的障碍物,分别是上管道和下管道
点击游戏界面,小鸟向上飞起,然后在重力作用下下坠,
当小鸟和管道碰撞后,结束界面弹出,同时小鸟落到地面

1.3 结束界面

GAMEOVER 提示面板
OK 按钮

2. 开发“开始界面”

考虑到草地的移动效果,我们在页面中加入两个草地

2.1 HTML

<!DOCTYPE html>
<html>
 <head>
  <meta charset="utf-8" />
  <title>Fly Bird</title>
  <link rel="stylesheet" type="text/css" href="css/index.css"/>
 </head>
 <body>
  <div id="wrapBg"> <!--游戏背景-->
   <div id="headTitle"> <!--开始标题-->
    <img id="headBird" src="img/bird0.png" alt="小鸟" /> <!--标题中的小鸟-->
   </div>
   <button id="startBtn" ></button> <!--开始按钮-->
   <div id="grassLand1"></div> <!--草地1-->
   <div id="grassLand2"></div> <!--草地2-->
  </div>
 </body>
</html>

2.2 CSS

#wrapBg{/*游戏背景*/
 width: 343px;height: 480px; 
 margin: 0 auto;
 background-image:url(../img/bg.jpg);
 position: relative;
 top: 100px;
 overflow: hidden;
}
#headTitle{/*开始标题*/
 width: 236px;height: 77px;
 background-image: url(../img/head.jpg);
 position: absolute; left: 53px; top: 100px;
}
#headBird{/*开始标题中的小鸟*/
 float:right;
 margin-top: 25px;
}
#startBtn{/*开始按钮*/
 width: 85px;height: 29px;
 padding: 0;margin: 0;
 background-image: url(../img/start.jpg);
 position: absolute;left: 129px;top: 250px;
}
#grassLand1{/*草地1*/
 height: 14px;width: 343px;
 background-image: url(../img/banner.jpg);
 position: absolute;top: 423px;
}
#grassLand2{/*草地2*/
 height: 14px;width: 343px;
 background-image: url(../img/banner.jpg);
 position: absolute;top: 423px;left: 343px;
}

将wrapBg中的overflow:hidden 注释掉的页面效果

JavaScript实现Fly Bird小游戏

开始界面.jpg

2.3 JS

小鸟煽动翅膀的效果需要用到逐帧动画的原理
逐帧动画是一种常见的动画形式(Frame By Frame),其原理是在“连续的关键帧”中分解动画动作,也就是在时间轴的每帧上逐帧绘制不同的内容,使其连续播放而成动画。

JavaScript实现Fly Bird小游戏

2.3.1 开始标题的摆动

var jsHeadTitle = document.getElementById("headTitle");// 获取标题
  var jsHeadBird = document.getElementById("headBird"); // 获取标题中小鸟

  var Y = 3;//标题的摆动幅度
  var index = 0;
  var imgArr = ["img/bird0.png","img/bird1.png"] 
  //将小鸟图片路径放入一个数组,利用逐帧动画的原理做出小鸟翅膀摆动的样子
  var headWaveTimer = setInterval(headWave,200); //设置标题上下摆动的定时器
  function headWave() {
   Y *= -1;
   jsHeadTitle.style.top = jsHeadTitle.offsetTop + Y + "px";
   jsHeadBird.src = imgArr[index++];
   if (index == 2) {
    index = 0;
   }
  }

2.3.2 移动的草地

var jsGrassLand1 = document.getElementById("grassLand1"); //获取草地1
  var jsGrassLand2 = document.getElementById("grassLand2"); //获取草地2

  var landTimer = setInterval(landRun,30); //让草地动起来的定时器
  function landRun() {
   if (jsGrassLand1.offsetLeft <= -343) {
    jsGrassLand1.style.left = "343px";
   }
   if (jsGrassLand2.offsetLeft <= -343) {
    jsGrassLand2.style.left = "343px";
   }
   jsGrassLand1.style.left = jsGrassLand1.offsetLeft - 3 + "px";
   jsGrassLand2.style.left = jsGrassLand2.offsetLeft - 3 + "px";
  }

2.3.3 Start按键

var jsStartBtn = document.getElementById("startBtn");
  jsStartBtn.onclick = function() { //为start按键添加点击事件处理程序
   jsHeadTitle.style.display = "none"; //隐藏标题
   clearInterval(headWaveTimer); //关闭让标题摆动的定时器
   jsStartBtn.style.display = "none"; //隐藏按键
   //待添加功能
   //点击开始按键进入游戏界面
  }

完成后的效果(注释掉了wrapBg中的overflow:hidden )

JavaScript实现Fly Bird小游戏

start01.gif

接下来我们开发“游戏界面”
3. “游戏界面”的开发
游戏界面中有三样元素,分别是“小鸟”,“障碍”,和“计分器”,我们依次来创建相应的对象。
3.1 小鸟
首先,创建小鸟的对象, bird.js 文件。

var bird = {
 flyTimer:null,//小鸟飞翔定时器
 wingTimer:null,//小鸟翅膀摆动定时器

 div:document.createElement("div"),
 showBird:function(parentObj) {
  this.div.style.width = "40px";
  this.div.style.height = "28px";
  this.div.style.backgroundImage = "url(img/bird0.png)";
  this.div.style.backgroundRepeat = "no-repeat";
  this.div.style.position = "absolute";
  this.div.style.left = "50px";
  this.div.style.top = "200px";
  this.div.style.zIndex = "1";

  parentObj.appendChild(this.div); //将小鸟DIV插入游戏界面中
 },

 fallSpeed: 0, //小鸟下落速度
 flyBird: function(){ //控制小鸟飞翔下落的函数
  bird.flyTimer = setInterval(fly,40);
  function fly() {
   bird.div.style.top = bird.div.offsetTop + bird.fallSpeed++ + "px";
   if (bird.div.offsetTop < 0) { 
    bird.fallSpeed = 2; //这里用于控制小鸟不要飞出界面
   }
   if (bird.div.offsetTop >= 395) {
    bird.fallSpeed = 0;
    clearInterval(bird.flyTimer); //一旦飞到地面,清除定时器
    clearInterval(bird.wingTimer); //清除翅膀摆动定时器
   }
   if (bird.fallSpeed > 12) {
    bird.fallSpeed = 12; //鸟的最大下落速度控制在12
   }
  }
 },

 wingWave: function() { //控制小鸟煽动翅膀的函数
  var up = ["url(img/up_bird0.png)", "url(img/up_bird1.png)"];
  var down = ["url(img/down_bird0.png)", "url(img/down_bird1.png)"];
  var i = 0, j = 0;
  bird.wingTimer = setInterval(wing,120);//逐帧动画,小鸟煽动翅膀
  function wing() {
   if (bird.fallSpeed > 0) {
    bird.div.style.backgroundImage = down[i++];
    if (i==2) {i = 0}
   }if (bird.fallSpeed < 0) {
    bird.div.style.backgroundImage = up[j++];
    if (j==2) {j = 0}
   }
  }
 }, 
};

下面,实现点击start按钮时,加载小鸟。(在之前的代码基础上添加)

jsStartBtn.onclick = function() { //为start按键添加点击事件处理程序
 jsHeadTitle.style.display = "none"; //隐藏标题
 clearInterval(headWaveTimer); //关闭让标题摆动的定时器
 jsStartBtn.style.display = "none"; //隐藏按键
 bird.showBird(jsWrapBg); //插入小鸟到界面中
 bird.flyBird(); //控制小鸟飞翔下落
 bird.wingWave(); //逐帧动画,小鸟煽动翅膀
 jsWrapBg.onclick = function(){
  bird.fallSpeed = -8;
 };
 //待添加功能
 //点击开始按键进入游戏界面
}

添加小鸟后的效果

JavaScript实现Fly Bird小游戏

play01.gif

3.2 障碍(上方水管和下方水管)

JavaScript实现Fly Bird小游戏

block示意图.png

障碍分为上方管道和下方管道,如示意图所示结构嵌套,这样就可以通过随机设置DownDiv2的高度和gapHeight的高度,来改变生成障碍的形态
block.js

function Block() {
 this.upDivWrap = null;
 this.downDivWrap = null;
 this.downHeight = baseObj.randomNum(0,150);
 this.gapHeight = baseObj.randomNum(150,160);
 this.upHeight = 312 - this.downHeight - this.gapHeight;

 // 用来生成Div的方法
 this.createDiv = function(url, height, positionType, left, top) {
  var newDiv = document.createElement("div");
  newDiv.style.width = "62px";
  newDiv.style.height = height;
  newDiv.style.position = positionType;
  newDiv.style.left = left;
  newDiv.style.top = top;
  newDiv.style.backgroundImage = url; //"url(/img/0.jpg)"
  return newDiv;
 };

 this.createBlock = function() {
  var upDiv1 = this.createDiv("url(img/up_mod.png)", this.upHeight + "px");
  var upDiv2 = this.createDiv("url(img/up_pipe.png)", "60px");
  this.upDivWrap = this.createDiv(null, null, "absolute", "450px");
  this.upDivWrap.appendChild(upDiv1);
  this.upDivWrap.appendChild(upDiv2);//生成上方管道

  var downDiv1 = this.createDiv("url(img/down_pipe.png)", "60px");
  var downDiv2 = this.createDiv("url(img/down_mod.png)", this.downHeight +"px");
  this.downDivWrap = this.createDiv(null, null, "absolute", "450px", 363 - this.downHeight + "px");
  this.downDivWrap.appendChild(downDiv1);
  this.downDivWrap.appendChild(downDiv2); //生成下方的管道

  jsWrapBg.appendChild(this.upDivWrap);
  jsWrapBg.appendChild(this.downDivWrap);
 };

 this.moveBlock = function() { //控制管道移动的方法
  this.upDivWrap.style.left = this.upDivWrap.offsetLeft - 3 + "px";
  this.downDivWrap.style.left = this.downDivWrap.offsetLeft - 3 + "px";
 }; 
}

公共对象文件 baseObj.js ,用来提供随机数,和两个矩形div的碰撞检测

var baseObj = {
 //随机数
 randomNum: function(min, max) {
  return parseInt(Math.random() * (max - min + 1) + min);
 },

 //两个矩形元素之间的碰撞检测
 rectangleCrashExamine: function (obj1, obj2) {
   var obj1Left = obj1.offsetLeft;
   var obj1Width = obj1.offsetLeft + obj1.offsetWidth;
   var obj1Top = obj1.offsetTop;
   var obj1Height = obj1.offsetTop + obj1.offsetHeight;

   var obj2Left = obj2.offsetLeft;
   var obj2Width = obj2.offsetLeft + obj2.offsetWidth;
   var obj2Top = obj2.offsetTop;
   var obj2Height = obj2.offsetTop + obj2.offsetHeight;

   if (!(obj1Left > obj2Width || obj1Width < obj2Left || obj1Top > obj2Height || obj1Height < obj2Top)) {
    return true;
   }
   return false;
 },
};

下面我的想法是在start按钮点击的时候创建一个block,把这个block存储到数组 blocksArr 中,在 landTimer 定时器的方法 landRun 中检查此数组的长度,如果数组不为空数组,那么就让数组中所有的block移动。
检查最后一个block离开的距离,达到一定距离,就重新new 一个block,添加到数组。
检查第一个block,一旦达到一定位置,就在结构中移除downDivWrap 和 upDivWrap,同时在数组中删除。

var landTimer = setInterval(landRun,30); //让草地动起来的定时器
  function landRun() {
   if (jsGrassLand1.offsetLeft <= -343) {
    jsGrassLand1.style.left = "343px";
   }
   if (jsGrassLand2.offsetLeft <= -343) {
    jsGrassLand2.style.left = "343px";
   }
   jsGrassLand1.style.left = jsGrassLand1.offsetLeft - 3 + "px";
   jsGrassLand2.style.left = jsGrassLand2.offsetLeft - 3 + "px";

   if (blocksArr.length) {
    for (var i = 0; i < blocksArr.length; i++) {
     blocksArr[i].moveBlock();
     var x =baseObj.rectangleCrashExamine(blocksArr[i].downDivWrap, bird.div);
     var y = baseObj.rectangleCrashExamine(blocksArr[i].upDivWrap, bird.div);
     var z = bird.div.offsetTop >= 390;
     if (x || y || z) {
      window.clearInterval(landTimer);//清除landTimer定时器
      bird.fallSpeed = 0; //小鸟下落
      jsWrapBg.onclick = null; //消除点击事件

     }
    }
    if (blocksArr[blocksArr.length - 1].downDivWrap.offsetLeft < (450 - blockDistance)) {
      blockDistance = baseObj.randomNum(130,250);
      var newBlock = new Block();
      newBlock.createBlock();
      blocksArr.push(newBlock);
    }

    if (blocksArr[0].downDivWrap.offsetLeft < -50) {
      jsWrapBg.removeChild(blocksArr[0].downDivWrap);
      jsWrapBg.removeChild(blocksArr[0].upDivWrap);
      blocksArr.shift(blocksArr[0]);
    }
   }
  }

当前的游戏效果

JavaScript实现Fly Bird小游戏

play02.gif

3.3 计分器

游戏中的计分器相对较好实现    

<div id="score">
    <div id="num1"></div>
    <div id="num2"></div>
    <div id="num3"></div>
   </div>
  var jsScore = document.getElementById("score");
  var jsNum1 = document.getElementById("num1");
  var jsNum2 = document.getElementById("num2");
  var jsNum3 = document.getElementById("num3");
  var score = 0;

今天先这样了,改天再写。哈哈

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

Javascript 相关文章推荐
一组JS创建和操作表格的函数集合
May 07 Javascript
Jquery Autocomplete 结合asp.net使用要点
Oct 29 Javascript
图片在浏览器中底部对齐 解决方法之一
Nov 30 Javascript
javascript history对象(历史记录)使用方法(实现浏览器前进后退)
Jan 07 Javascript
聊一聊JavaScript作用域和作用域链
May 03 Javascript
JS全角与半角转化实例(分享)
Jul 04 Javascript
原生js实现简单的链式操作
Jul 04 Javascript
JS+jQuery实现注册信息的验证功能
Sep 26 jQuery
vsCode安装使用教程和插件安装方法
Aug 24 Javascript
Three.js实现3D机房效果
Dec 30 Javascript
vue-router命名路由和编程式路由传参讲解
Jan 19 Javascript
微信小程序使用echarts获取数据并生成折线图
Oct 16 Javascript
JS中对数组元素进行增删改移的方法总结
Dec 15 #Javascript
JS去除重复并统计数量的实现方法
Dec 15 #Javascript
javascript基于原型链的继承及call和apply函数用法分析
Dec 15 #Javascript
移动端脚本框架Hammer.js
Dec 15 #Javascript
WEB开发之注册页面验证码倒计时代码的实现
Dec 15 #Javascript
浅谈javascript alert和confirm的美化
Dec 15 #Javascript
JavaScript模板引擎Template.js使用详解
Dec 15 #Javascript
You might like
使用NetBeans + Xdebug调试PHP程序的方法
2011/04/12 PHP
php多文件上传功能实现原理及代码
2013/04/18 PHP
php7 参数、整形及字符串处理机制修改实例分析
2020/05/25 PHP
javascript之对系统的toFixed()方法的修正
2007/05/08 Javascript
二行代码解决全部网页木马
2008/03/28 Javascript
jquery ajax 检测用户注册时用户名是否存在
2009/11/03 Javascript
js实现简单的星级选择器提交效果适用于评论等
2013/10/18 Javascript
什么是 AngularJS?AngularJS简介
2014/12/06 Javascript
分享两个手机访问pc网站自动跳转手机端网站代码
2020/12/24 Javascript
jQuery判断数组是否包含了指定的元素
2015/03/10 Javascript
使用impress.js制作幻灯片
2015/09/09 Javascript
基于javascript实现tab切换特效
2016/03/29 Javascript
javascript加减乘除的简单实例
2016/07/12 Javascript
jQuery EasyUI常用数据验证汇总
2016/09/18 Javascript
微信小程序  modal弹框组件详解
2016/10/27 Javascript
bootstrap 设置checkbox部分选中效果
2017/04/20 Javascript
详解如何使用Node.js编写命令工具——以vue-cli为例
2017/06/29 Javascript
Vue.js项目部署到服务器的详细步骤
2017/07/17 Javascript
js处理包含中文的字符串实例
2017/10/11 Javascript
bootstrap模态框关闭后清除模态框的数据方法
2018/08/10 Javascript
python3.3使用tkinter开发猜数字游戏示例
2014/03/14 Python
python下MySQLdb用法实例分析
2015/06/08 Python
Python守护线程用法实例
2017/06/23 Python
python读取txt文件中特定位置字符的方法
2018/12/24 Python
python实现网页自动签到功能
2019/01/21 Python
详解Python并发编程之从性能角度来初探并发编程
2019/08/23 Python
在Python中使用turtle绘制多个同心圆示例
2019/11/23 Python
浅析NumPy 切片和索引
2020/09/02 Python
moosejaw旗下的户外商品促销网站:Mountain Steals
2017/02/27 全球购物
一名老师的自我评价
2014/02/07 职场文书
危爆物品安全大检查大整治工作方案
2014/05/03 职场文书
课外活动总结范文
2014/07/09 职场文书
2014年纪检部工作总结
2014/11/12 职场文书
《纸船和风筝》教学反思
2016/02/18 职场文书
pytorch中的numel函数用法说明
2021/05/13 Python
python 中的jieba分词库
2021/11/23 Python