亚洲乱码中文字幕综合,中国熟女仑乱hd,亚洲精品乱拍国产一区二区三区,一本大道卡一卡二卡三乱码全集资源,又粗又黄又硬又爽的免费视频

JavaScript實(shí)現(xiàn)Fly Bird小游戲

 更新時(shí)間:2016年12月15日 10:15:25   作者:Runner_Yang  
這篇文章主要為大家詳細(xì)介紹了JavaScript實(shí)現(xiàn)Fly Bird小游戲的制作方法,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下

本教程為大家分享了Fly Bird小游戲的制作流程,供大家參考,具體內(nèi)容如下

1.分析頁(yè)面結(jié)構(gòu),理清需求和功能

游戲有三個(gè)界面,分別是開始界面,游戲界面和游戲結(jié)束界面。

1.1 開始界面

start.gif

游戲的大背景
上下移動(dòng)的游戲標(biāo)題和翅膀擺動(dòng)的小鳥
start 按鈕,點(diǎn)擊進(jìn)入游戲界面
一直移動(dòng)的地面

1.2 游戲界面

play.gif

顯示越過障礙數(shù)量的計(jì)分器
移動(dòng)的障礙物,分別是上管道和下管道
點(diǎn)擊游戲界面,小鳥向上飛起,然后在重力作用下下墜,
當(dāng)小鳥和管道碰撞后,結(jié)束界面彈出,同時(shí)小鳥落到地面

1.3 結(jié)束界面

GAMEOVER 提示面板
OK 按鈕

2. 開發(fā)“開始界面”

考慮到草地的移動(dòng)效果,我們?cè)陧?yè)面中加入兩個(gè)草地

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"> <!--開始標(biāo)題-->
    <img id="headBird" src="img/bird0.png" alt="小鳥" /> <!--標(biāo)題中的小鳥-->
   </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{/*開始標(biāo)題*/
 width: 236px;height: 77px;
 background-image: url(../img/head.jpg);
 position: absolute; left: 53px; top: 100px;
}
#headBird{/*開始標(biāo)題中的小鳥*/
 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 注釋掉的頁(yè)面效果

開始界面.jpg

2.3 JS

小鳥煽動(dòng)翅膀的效果需要用到逐幀動(dòng)畫的原理
逐幀動(dòng)畫是一種常見的動(dòng)畫形式(Frame By Frame),其原理是在“連續(xù)的關(guān)鍵幀”中分解動(dòng)畫動(dòng)作,也就是在時(shí)間軸的每幀上逐幀繪制不同的內(nèi)容,使其連續(xù)播放而成動(dòng)畫。

2.3.1 開始標(biāo)題的擺動(dòng)

 var jsHeadTitle = document.getElementById("headTitle");// 獲取標(biāo)題
  var jsHeadBird = document.getElementById("headBird"); // 獲取標(biāo)題中小鳥

  var Y = 3;//標(biāo)題的擺動(dòng)幅度
  var index = 0;
  var imgArr = ["img/bird0.png","img/bird1.png"] 
  //將小鳥圖片路徑放入一個(gè)數(shù)組,利用逐幀動(dòng)畫的原理做出小鳥翅膀擺動(dòng)的樣子
  var headWaveTimer = setInterval(headWave,200); //設(shè)置標(biāo)題上下擺動(dòng)的定時(shí)器
  function headWave() {
   Y *= -1;
   jsHeadTitle.style.top = jsHeadTitle.offsetTop + Y + "px";
   jsHeadBird.src = imgArr[index++];
   if (index == 2) {
    index = 0;
   }
  }

2.3.2 移動(dòng)的草地

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

  var landTimer = setInterval(landRun,30); //讓草地動(dòng)起來的定時(shí)器
  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按鍵添加點(diǎn)擊事件處理程序
   jsHeadTitle.style.display = "none"; //隱藏標(biāo)題
   clearInterval(headWaveTimer); //關(guān)閉讓標(biāo)題擺動(dòng)的定時(shí)器
   jsStartBtn.style.display = "none"; //隱藏按鍵
   //待添加功能
   //點(diǎn)擊開始按鍵進(jìn)入游戲界面
  }

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

start01.gif

接下來我們開發(fā)“游戲界面”
3. “游戲界面”的開發(fā)
游戲界面中有三樣元素,分別是“小鳥”,“障礙”,和“計(jì)分器”,我們依次來創(chuàng)建相應(yīng)的對(duì)象。
3.1 小鳥
首先,創(chuàng)建小鳥的對(duì)象, bird.js 文件。

var bird = {
 flyTimer:null,//小鳥飛翔定時(shí)器
 wingTimer:null,//小鳥翅膀擺動(dòng)定時(shí)器

 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(){ //控制小鳥飛翔下落的函數(shù)
  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); //一旦飛到地面,清除定時(shí)器
    clearInterval(bird.wingTimer); //清除翅膀擺動(dòng)定時(shí)器
   }
   if (bird.fallSpeed > 12) {
    bird.fallSpeed = 12; //鳥的最大下落速度控制在12
   }
  }
 },

 wingWave: function() { //控制小鳥煽動(dòng)翅膀的函數(shù)
  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);//逐幀動(dòng)畫,小鳥煽動(dòng)翅膀
  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}
   }
  }
 }, 
};

下面,實(shí)現(xiàn)點(diǎn)擊start按鈕時(shí),加載小鳥。(在之前的代碼基礎(chǔ)上添加)

jsStartBtn.onclick = function() { //為start按鍵添加點(diǎn)擊事件處理程序
 jsHeadTitle.style.display = "none"; //隱藏標(biāo)題
 clearInterval(headWaveTimer); //關(guān)閉讓標(biāo)題擺動(dòng)的定時(shí)器
 jsStartBtn.style.display = "none"; //隱藏按鍵
 bird.showBird(jsWrapBg); //插入小鳥到界面中
 bird.flyBird(); //控制小鳥飛翔下落
 bird.wingWave(); //逐幀動(dòng)畫,小鳥煽動(dòng)翅膀
 jsWrapBg.onclick = function(){
  bird.fallSpeed = -8;
 };
 //待添加功能
 //點(diǎn)擊開始按鍵進(jìn)入游戲界面
}

添加小鳥后的效果

play01.gif

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

block示意圖.png

障礙分為上方管道和下方管道,如示意圖所示結(jié)構(gòu)嵌套,這樣就可以通過隨機(jī)設(shè)置DownDiv2的高度和gapHeight的高度,來改變生成障礙的形態(tài)
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() { //控制管道移動(dòng)的方法
  this.upDivWrap.style.left = this.upDivWrap.offsetLeft - 3 + "px";
  this.downDivWrap.style.left = this.downDivWrap.offsetLeft - 3 + "px";
 }; 
}

公共對(duì)象文件 baseObj.js ,用來提供隨機(jī)數(shù),和兩個(gè)矩形div的碰撞檢測(cè)

var baseObj = {
 //隨機(jī)數(shù)
 randomNum: function(min, max) {
  return parseInt(Math.random() * (max - min + 1) + min);
 },

 //兩個(gè)矩形元素之間的碰撞檢測(cè)
 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按鈕點(diǎn)擊的時(shí)候創(chuàng)建一個(gè)block,把這個(gè)block存儲(chǔ)到數(shù)組 blocksArr 中,在 landTimer 定時(shí)器的方法 landRun 中檢查此數(shù)組的長(zhǎng)度,如果數(shù)組不為空數(shù)組,那么就讓數(shù)組中所有的block移動(dòng)。
檢查最后一個(gè)block離開的距離,達(dá)到一定距離,就重新new 一個(gè)block,添加到數(shù)組。
檢查第一個(gè)block,一旦達(dá)到一定位置,就在結(jié)構(gòu)中移除downDivWrap 和 upDivWrap,同時(shí)在數(shù)組中刪除。

  var landTimer = setInterval(landRun,30); //讓草地動(dòng)起來的定時(shí)器
  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定時(shí)器
      bird.fallSpeed = 0; //小鳥下落
      jsWrapBg.onclick = null; //消除點(diǎn)擊事件

     }
    }
    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]);
    }
   }
  }

當(dāng)前的游戲效果

play02.gif

3.3 計(jì)分器

游戲中的計(jì)分器相對(duì)較好實(shí)現(xiàn)    

  <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;

今天先這樣了,改天再寫。哈哈

以上就是本文的全部?jī)?nèi)容,希望對(duì)大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。

相關(guān)文章

最新評(píng)論