本教程為大家分享了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;
今天先這樣了,改天再寫。哈哈
以上就是本文的全部內容,希望對大家的學習有所幫助,也希望大家多多支持。