陳豪
摘要:該文分析了使用Unity3D設(shè)計(jì)飛行類Android游戲的方法和過(guò)程,包括背景的設(shè)置、主角飛機(jī)的制作,敵機(jī)的制作,子彈的制作,這些游戲物體之間的碰撞反應(yīng)和玩家控制游戲的方法,使用C#語(yǔ)言來(lái)編寫游戲程序,包括用代碼控制場(chǎng)景的切換,飛機(jī)、子彈、獎(jiǎng)勵(lì)物品的自由落體或者飛行,碰撞之后發(fā)生的效果以及變化等等。最后對(duì)游戲進(jìn)行了測(cè)試與總結(jié)。
關(guān)鍵詞:Unity3D;飛行類游戲;C#編程;碰撞檢測(cè)
中圖分類號(hào):TP391 文獻(xiàn)標(biāo)識(shí)碼:A 文章編號(hào):1009-3044(2015)30-0168-03
飛行類游戲在社交媒體上傳播與流行,尤其是設(shè)計(jì)簡(jiǎn)潔、玩法直接的小型化飛機(jī)游戲尤其受到歡迎。通過(guò)使用Unity3D引擎,可以快速開(kāi)發(fā)出飛行游戲。利用Unity3D提供的游戲?qū)ο?、碰撞探測(cè)和控制輸入等功能,讓開(kāi)發(fā)者無(wú)需從底層開(kāi)始開(kāi)發(fā),通過(guò)點(diǎn)選操作,輔助以少量C#代碼便可以所操即所見(jiàn)、所見(jiàn)即所得,即時(shí)看到游戲的效果進(jìn)行快速開(kāi)發(fā)。本項(xiàng)目美工方面用Photpshop、3DS Max等軟件簡(jiǎn)單進(jìn)行處理,滿足項(xiàng)目的要求UI與游戲美術(shù)要求。
1 總體設(shè)計(jì)
起初設(shè)計(jì)飛機(jī)射擊游戲靈感來(lái)源于微信的“打飛機(jī)”游戲,在微信上好友一起競(jìng)技比拼所獲得的分?jǐn)?shù),這里還包含網(wǎng)絡(luò)通信設(shè)計(jì),本文不涉及。單機(jī)的飛機(jī)射擊游戲要考慮很多因素,比如積分,一些玩法上和界面上的設(shè)計(jì)等方面。界面上設(shè)計(jì)包括使用不同的飛機(jī)、子彈要素,幾種爆炸效果,碰撞獎(jiǎng)勵(lì)物品效果等。玩法上包括子彈獎(jiǎng)勵(lì)和TNT炸彈獎(jiǎng)勵(lì),這兩種將獎(jiǎng)勵(lì)物品隨機(jī)出現(xiàn),一種是子彈的獎(jiǎng)勵(lì),將原本中間一路子彈變成側(cè)翼的兩路子彈;另一種則是威力強(qiáng)大的TNT炸彈獎(jiǎng)勵(lì),能夠清空屏幕內(nèi)所有的敵機(jī)。游戲失敗的情況設(shè)計(jì),敵機(jī)與玩家控制的飛機(jī)產(chǎn)生碰撞后進(jìn)入失敗畫面。敵機(jī)設(shè)計(jì)上,敵機(jī)不產(chǎn)生子彈,玩家只需要躲避屏幕上方下落的敵機(jī)即可。子彈的獎(jiǎng)勵(lì)是有固定的持續(xù)時(shí)間,TNT炸彈獎(jiǎng)勵(lì)可以儲(chǔ)存累加,點(diǎn)擊右下角的炸彈的小圖標(biāo)使用。游戲的操作是通過(guò)手指控制主角飛機(jī)移動(dòng),玩家躲避敵機(jī)并可以接受在敵機(jī)中降落的獎(jiǎng)勵(lì)物品。子彈是跟隨主角的移動(dòng)而移動(dòng),所以只需要把自身飛機(jī)(即是子彈的軌跡)瞄準(zhǔn)到敵機(jī)即可擊落敵機(jī),設(shè)計(jì)得盡量操作簡(jiǎn)單些。
開(kāi)發(fā)工具使用Unity3D,平臺(tái)為Android操作系統(tǒng)。利用Unity的Level功能,預(yù)設(shè)計(jì)游戲提供三種關(guān)卡,第一種叫做經(jīng)典模式,即普通的飛機(jī)游戲。第二種是瘋狂模式,敵機(jī)下落的速率以及血量都有提升,同樣玩家控制的飛機(jī)發(fā)出的子彈威力也更大。第三種是換機(jī)模式,玩家控制的飛機(jī)換了模型,換了模型之后的飛機(jī),在參數(shù)上,設(shè)置了威力更大的子彈(子彈出現(xiàn)的速率高),獎(jiǎng)勵(lì)物品的威力也同時(shí)加強(qiáng)。
2 游戲?qū)ο?/p>
2.1 游戲背景與主角飛行效果
整個(gè)游戲的背景產(chǎn)用兩張貼圖的疊加。采用代碼控制兩張同樣的貼圖交替移動(dòng),實(shí)現(xiàn)背景的移動(dòng),導(dǎo)入飛機(jī)后就能夠產(chǎn)生飛機(jī)移動(dòng)的效果。關(guān)鍵代碼包括,要在外部定義公有變量設(shè)置移動(dòng)的速度,這里必須要注意是要設(shè)置為靜態(tài)變量,否則運(yùn)行程序會(huì)報(bào)錯(cuò)。關(guān)鍵代碼如下。
public static float moveSpeed=4f;
接下來(lái)實(shí)現(xiàn)背景圖的移動(dòng)。跟隨時(shí)間變化進(jìn)行下移。
this.transform.Translate(Vector3.down*moveSpeed*Time.deltaTime);
一旦超過(guò)攝像機(jī)的范圍,單張背景圖就應(yīng)該移動(dòng)到新的位置。
if(postion.y<=-8.52f) {
this.transform.position=new Vector3(postion.x,postion.y+8.52f*2,postion.z);
}
其中,8.52f是由背景圖片的高像素決定的,圖片高為852像素。
飛機(jī)的飛行,單張的飛機(jī)素材是不行的?,F(xiàn)在已經(jīng)實(shí)現(xiàn)了背景的移動(dòng),以背景為參照物,飛機(jī)已經(jīng)在飛行?,F(xiàn)在要產(chǎn)生飛機(jī)的飛行效果。使用兩張不同飛機(jī)尾部燃燒效果,首先定義精靈圖組,鍵入以下關(guān)鍵代碼。然后在Inspector面板中進(jìn)行選擇貼圖,即能實(shí)現(xiàn)飛機(jī)噴氣飛行效果。完成效果如圖1所示。
if(animation){
timer+=Time.deltaTime;
int frameIndex = (int)(timer/(1f/frameCountPersconds));
int frame = frameIndex%2;
spriteRender.sprite = sprites[frame];
}
2.2 敵機(jī)的產(chǎn)生
上面已經(jīng)實(shí)現(xiàn)了主角飛機(jī)的飛行移動(dòng),接下來(lái)需要在屏幕內(nèi)隨機(jī)產(chǎn)生敵機(jī)。敵機(jī)在屏幕上方自動(dòng)生成,移動(dòng)到屏幕下方之后重新定位到屏幕上方,總數(shù)量固定從而節(jié)約游戲運(yùn)行內(nèi)存。在Unity3D中建立一個(gè)空的Object,由它來(lái)隨機(jī)產(chǎn)生敵機(jī)。在隨機(jī)產(chǎn)生敵機(jī)之前,導(dǎo)入敵機(jī)的預(yù)制(Prefabs),直接從素材圖片(Images)文件中拖動(dòng)至Hierarchy面板中。Spawn是新建的空的Object。在其中綁定代碼,需要定義各類不同的敵機(jī)出現(xiàn)速率,定義過(guò)程如圖2所示。
public float enemy0Rate = 1.5f;//定義一種敵機(jī)出現(xiàn)的速率
同時(shí),需要設(shè)置獎(jiǎng)勵(lì)物品的出現(xiàn)速率。有兩種不同的獎(jiǎng)勵(lì)物品,因?yàn)橥Σ煌?,出現(xiàn)的速率也不一樣。
public float awardType0Rate = 8f;
定義好之后,需要注意隨機(jī)產(chǎn)生的敵機(jī)或者獎(jiǎng)勵(lì)物品,需要在超出一定范圍之后消失,不然產(chǎn)生的物體一直會(huì)存在,會(huì)占用內(nèi)存。敵機(jī)定義的參數(shù)如圖2所示。
public void createEnemy0(){
float x= Random.Range(-1.7f,1.7f);
GameObject.Instantiate(enemy0Prefab,new Vector3(x,transform.position.y),Quaternion.identity);
}
以上代碼表示當(dāng)超過(guò)某個(gè)位置,敵機(jī)就應(yīng)該消失。
2.3 子彈的發(fā)射
子彈在Unity3D設(shè)定為預(yù)制。將它們拖到主角(hero)的對(duì)象下,即為hero的子對(duì)象。調(diào)整好他們的位置,正好在左右以及中間。接下來(lái)給子彈綁定代碼。讓子彈能夠按照給定的速度自動(dòng)向上升。非常簡(jiǎn)單,只需要給一個(gè)速度即可以實(shí)現(xiàn)
public float rate =2f;
和敵機(jī)一樣,需要在超出屏幕范圍之后使子彈消失。
3 碰撞與控制效果
3.1 子彈與敵機(jī)發(fā)生碰撞
在碰撞之前,要給需要碰撞的物體加上剛體,也就是collider。給敵機(jī)的預(yù)制,主角的預(yù)制以及獎(jiǎng)勵(lì)物品的預(yù)制都添加上了Polygon Collider 2D。給子彈加上Box Collider2D。給子彈以及敵機(jī)以及主角hero加上剛體之后,就可以通過(guò)代碼實(shí)現(xiàn)碰撞了。一定要給需要碰撞的物體加上剛體,否則將不會(huì)發(fā)生碰撞。
檢測(cè)碰撞設(shè)置時(shí)首先要設(shè)置標(biāo)簽(Tag),要為需要碰撞的物體設(shè)置標(biāo)簽,標(biāo)簽是可以重復(fù)的使用的,即不同的物體可以使用同一個(gè)標(biāo)簽。那就給同一類物體標(biāo)上同一個(gè)標(biāo)簽,比如給敵機(jī)全都設(shè)置為”Emeny”。這樣一來(lái)就可以判斷是否碰撞到了敵機(jī)。同樣的,主角碰撞獎(jiǎng)勵(lì)物品,子彈碰撞敵機(jī),敵機(jī)碰撞主角,都是同樣的方法。在這里列舉主角碰撞獎(jiǎng)勵(lì)物品的代碼:
public IEnumerator OnTriggerEnter2D(Collider2D collider){
if(collider.tag=="Award"){};
}
上述代碼中的tag=="Award",就是找到“Award”標(biāo)簽。
3.2 主角的控制
游戲是基于Android平臺(tái)開(kāi)發(fā)的手機(jī)游戲,所以采用觸屏方式控制主角飛機(jī),玩家通過(guò)手指的操控就可以實(shí)現(xiàn)飛機(jī)的移動(dòng)。在unity軟件中,可以編寫控制代碼控制鼠標(biāo)的移動(dòng),導(dǎo)出成Android平臺(tái)相當(dāng)于在手機(jī)上手指移動(dòng)控制飛機(jī)。
private void checkPosition(){
Vector3 pos = transform.position;
float x = pos.x;
float y = pos.y;
if(x<-1.8f){ x=-1.8f; }
if(x>1.8f){ x=1.8f; }
if(y<-3.4f){ y=-3.4f; }
if(y>3.4f){ y=3.4f; }
transform.position= new Vector3(x,y,0);
}
直接使用checkPosition,檢測(cè)鼠標(biāo)(或者是手指)的位置。要保證的飛機(jī)不飛出屏幕外部,即在x,y軸上,正負(fù)都不超過(guò)屏幕的寬度。主角的飛機(jī)的像素為100*114,在unity中屏幕的寬和長(zhǎng)為480*852。拖動(dòng)主角的飛機(jī),如圖7中,在position中能檢測(cè)x和y軸,拖動(dòng)到屏幕邊緣,發(fā)現(xiàn)position中x為正負(fù)1.8,而上下移動(dòng)的時(shí)候,發(fā)現(xiàn)y為正負(fù)3.4。因此在代碼中書(shū)寫鼠標(biāo)(或手指)移動(dòng)的范圍左右是1.8f,上下則是3.4f。主角坐標(biāo)控制的設(shè)置如圖3所示。
4 結(jié)束語(yǔ)
通過(guò)Unity的Building功能導(dǎo)出游戲。在Build Setting中設(shè)定選項(xiàng)后導(dǎo)出APK文件,通過(guò)手機(jī)助手拷貝到Android手機(jī)上,安裝后運(yùn)行,經(jīng)測(cè)試可以順利玩起來(lái)無(wú)問(wèn)題,測(cè)試效果如圖4所示。制作過(guò)程中除了主要的unity之外,使用Photoshop,3DS Max制作素材,使用C#語(yǔ)言代碼實(shí)現(xiàn)控制,還可以使用視頻軟件片頭片尾導(dǎo)出成apk格式,難點(diǎn)在于如何在unity中播放幀動(dòng)畫(即在游戲中的敵機(jī)爆炸死亡動(dòng)畫),如何使物體進(jìn)行碰撞(collider),是否考慮重力(Is Trigger)以及判斷碰撞之后進(jìn)行的一系列操作等等。
總結(jié)整個(gè)設(shè)計(jì)過(guò)程,使用unity3D制作飛行類游戲,可以很方便地包括設(shè)計(jì)敵機(jī)的碰撞、飛行速度,碰撞觸發(fā)的效果,使用產(chǎn)卵器(spawn)隨機(jī)產(chǎn)生敵機(jī),并控制敵機(jī)出現(xiàn)的速率。游戲的操作通過(guò)手機(jī)觸碰屏幕,跟隨手指移動(dòng)方向移動(dòng)敵機(jī)。飛機(jī)主角的可以通過(guò)手指點(diǎn)選移動(dòng)并操控,同時(shí)自動(dòng)發(fā)射子彈。游戲物體之間的碰撞時(shí)通過(guò)坐標(biāo)檢測(cè),一旦發(fā)生碰撞便出發(fā)C#代碼的所寫的效果。限于本文篇幅,游戲其他部分如計(jì)分代碼實(shí)現(xiàn)、片頭片尾動(dòng)畫實(shí)現(xiàn)等將在以后逐步完善。
參考文獻(xiàn):
[1] 李發(fā)陵.軟件工程[M]. 北京: 清華大學(xué)出版社, 2013: 212.
[2] Ryan Henson Creighton. Unity 3.x 游戲開(kāi)發(fā)實(shí)例[M]. 師蓉,譯.北京: 人民郵電出版社, 2013: 324.
[3] 周德云.Flash動(dòng)畫制作與應(yīng)用[M].北京: 人民郵電出版社, 2012: 352.
[4] 吳亞峰.Android3D游戲案例開(kāi)發(fā)大全[M].北京:人民郵電出版社, 2013: 648.
[5] 宣雨松. unity3D游戲開(kāi)發(fā)[M].北京:人民郵電出版社, 2012: 334.