DIV CSS 佈局教程網

 DIV+CSS佈局教程網 >> 網頁腳本 >> JavaScript入門知識 >> 關於JavaScript >> JavaScript實現Fly Bird小游戲
JavaScript實現Fly Bird小游戲
編輯:關於JavaScript     

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

1.分析頁面結構,理清需求和功能

游戲有三個界面,分別是開始界面,游戲界面和游戲結束界面。

1.1 開始界面

start.gif

游戲的大背景
上下移動的游戲標題和翅膀擺動的小鳥
start 按鈕,點擊進入游戲界面
一直移動的地面

1.2 游戲界面

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 注釋掉的頁面效果

開始界面.jpg

2.3 JS

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

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 )

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;
 };
 //待添加功能
 //點擊開始按鍵進入游戲界面
}

添加小鳥後的效果

play01.gif

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

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

當前的游戲效果

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;

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

以上就是本文的全部內容,希望對大家的學習有所幫助,也希望大家多多支持。

XML學習教程| jQuery入門知識| AJAX入門| Dreamweaver教程| Fireworks入門知識| SEO技巧| SEO優化集錦|
Copyright © DIV+CSS佈局教程網 All Rights Reserved