版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請進(jìn)行舉報或認(rèn)領(lǐng)
文檔簡介
1、<p><b> 1 緒論</b></p><p> 1.1 手機(jī)軟件現(xiàn)狀</p><p> 在信息社會中,手機(jī)及其他無線設(shè)備越來越多的走進(jìn)普通百姓的工作和生活,隨著信息網(wǎng)絡(luò)化的不斷進(jìn)展,手機(jī)及其他無線設(shè)備上網(wǎng)絡(luò)勢在必行。但是傳統(tǒng)手機(jī)存在以下弊端:</p><p> 1. 傳統(tǒng)手機(jī)出廠時均由硬件廠商固化程序,程序不能增加、
2、刪除,有了錯誤也不能更新、修改,若要增加新功能必須另換一部手機(jī)。</p><p> 2. 傳統(tǒng)手機(jī)訪問互聯(lián)網(wǎng)是通過WAP(Wireless Application Protocal),所有網(wǎng)絡(luò)資源必須接通網(wǎng)絡(luò)才能在線訪問,非常耗時、費(fèi)用亦很高。</p><p> 而Java技術(shù)在無線應(yīng)用方面的優(yōu)勢非常明顯:</p><p> 1. 應(yīng)用程序可按需下載,而不
3、是購買由硬件商提供的套件,可升級空間大。</p><p> 2. Java技術(shù)提供了一個類庫,它使的應(yīng)用開發(fā)商可以創(chuàng)建更為直覺、豐富的用戶界面(GUI);</p><p> 3. Java技術(shù)使網(wǎng)絡(luò)帶寬的應(yīng)用更為有效,因?yàn)閼?yīng)用程序可以下載到器件上,并在本地運(yùn)行,僅僅是在連接到服務(wù)器時才會占用網(wǎng)絡(luò)帶寬。</p><p> 基于以上分析,Java手機(jī)將是未來手
4、機(jī)的發(fā)展方向,是業(yè)界的熱點(diǎn)。</p><p> 1.2 J2ME介紹</p><p> 雖然 Java 已經(jīng)被用到許多企業(yè)級軟體上,可是其實(shí)骨子里面還是非常適合用在嵌入式系統(tǒng)之中。Java平臺演進(jìn)到Java2后,Java平臺分別針對不同領(lǐng)域的需求被分成四個版本,亦即J2EE、J2SE、J2ME以及JavaCard。其中J2ME定位在消費(fèi)性電子產(chǎn)品的應(yīng)用上。這個版本針對資源有限的電子消費(fèi)
5、產(chǎn)品的需求精簡核心類庫,并提供了模塊化的架構(gòu)讓不同類型產(chǎn)品能夠隨時增加支持的能力。這個版本的應(yīng)用層面相當(dāng)廣泛,會是未來Java平臺發(fā)展的重點(diǎn)項目。</p><p> J2ME在1999年的JavaOne開發(fā)人員大會上初次亮相,它的目標(biāo)是面向智能無線設(shè)備和小型計算機(jī)設(shè)備的開發(fā)人員。J2ME的一個關(guān)鍵優(yōu)點(diǎn)是,J2ME與所有支持Java的設(shè)備都是兼容的。支持Java的設(shè)備就是任何運(yùn)行Java虛擬機(jī)器的計算機(jī)。Moto
6、rola、Nokia等生產(chǎn)廠商都生產(chǎn)支持Java的設(shè)備。、</p><p> J2ME平臺是由配置(Configuration)和簡表(Profile)構(gòu)成的。配置是提供給最大范圍設(shè)備使用的最小類庫集合,在配置中同時包含Java虛擬機(jī)。簡表是針對一系列設(shè)備</p><p> 提供的開發(fā)包集合。在J2ME中還有一個重要的概念是可選包(Optional Package),它是針對特定設(shè)備提
7、供的類庫,比如某些設(shè)備是支持藍(lán)牙的,針對此功能J2ME中制定了JSR82(Bluetooth API)提供了對藍(lán)牙的支持。</p><p> 目前,J2ME中有兩個最主要的配置,分別是Connected Limited Devices Configuration(CLDC)和Connected Devices Configuration(CDC)。</p><p> 作為第一個面對小型
8、設(shè)備的Java應(yīng)用開發(fā)規(guī)范,CLDC是由包括Nokia,Motorola和Siemens在內(nèi)的18家全球知名公司共同協(xié)商完成的。CLDC是J2ME核心配置中的一個,可以支持一個或多個profile。其目標(biāo)主要面向小型的、網(wǎng)絡(luò)連接速度慢、能源有限(主要是電池供電)且資源有限的設(shè)備,如手機(jī)、PDA等。</p><p> 而CDC則是主要用于運(yùn)算能力相對較佳、在電力供應(yīng)上相對比較充足的嵌入式裝置 (比方說冷氣機(jī)、電冰
9、箱、電視機(jī)機(jī)頂盒 (set-top box))</p><p> 1.3 手機(jī)游戲應(yīng)具有的特征</p><p> 一個手機(jī)游戲應(yīng)該具有以下特征:</p><p> 易于學(xué)習(xí): 既然手機(jī)游戲面向的是普通消費(fèi)者而不是計算機(jī)專家,那么他們不可能深入的學(xué)習(xí)游戲技巧。消費(fèi)者不會花幾個小時去研究一個3元的手動操作的游戲。保持游戲的簡單是最基本的要求。</p>
10、<p> 可中斷性: 多任務(wù)處理是手機(jī)生活方式的基本特征。手機(jī)用戶常常在任務(wù)(如等一個電子郵件或者等車)之間有一小段時間。而游戲、日歷管理、通訊和工作數(shù)據(jù)訪問使用的是同一個設(shè)備。所以一個好的手機(jī)游戲應(yīng)該提供短時間的娛樂功能,并且允許用戶在游戲和工作模式之間順利切換。</p><p> 基于訂閱:手機(jī)游戲的盈利成功取決于他們巨大的使用量。一開始開發(fā)和設(shè)計每個游戲都是昂貴的。如果一個手機(jī)游戲開發(fā)者要贏
11、利的話,重要的是:同一個游戲引擎,多個標(biāo)題,基本的故事情節(jié)類似?;谟嗛喌挠螒蚴遣粩喈a(chǎn)生收入的最好方法。 </p><p> 豐富的社會交互: 不管一個游戲設(shè)計得多好,只要玩家找到了它的根本模式或者玩完了所有的游戲路徑很快就會厭煩這個游戲。對于一個基于訂閱的游戲,重要的是與別的玩家合作以增強(qiáng)所玩游戲的智力和隨機(jī)性。在今天紛繁復(fù)雜的多玩家游戲中具有豐富社會交互的游戲證明是成功的。</p><p
12、> 利用手機(jī)技術(shù)的優(yōu)點(diǎn): 巨額的手機(jī)技術(shù)研發(fā)費(fèi)用都花在提高設(shè)備和網(wǎng)絡(luò)的可用性和可靠性上面。因此,手機(jī)設(shè)備硬件和網(wǎng)絡(luò)協(xié)議與桌面/控制臺世界(如全球定位系統(tǒng)(GPS)擴(kuò)展、條形碼掃描儀、和短消息服務(wù)(SMS)/多媒體信息服務(wù)(MMS)通訊)有著非常大的差別。好的手機(jī)游戲應(yīng)該利用那些更新的設(shè)備特征和網(wǎng)絡(luò)基礎(chǔ)設(shè)備的優(yōu)點(diǎn)。</p><p> 1.4 本游戲背景介紹</p><p> 在抗
13、戰(zhàn)中,由國民政府領(lǐng)導(dǎo)的中國空軍是所有國民黨軍隊中抗戰(zhàn)最為徹底,也最為英勇的部隊,雖然開戰(zhàn)之初力量懸殊,但是面對窮兇極惡的日本侵略者,他們毫不畏懼,視死如歸,全力以赴投身到民族救亡的偉業(yè)中去,用自己的鮮血和生命譜寫了中華民族最為豪邁的詩篇。自一九三二年二月五日“一·二八”事件始,至一九四五年八月十四日止,抗戰(zhàn)期間,共出動飛機(jī)一千一百二十八批,八千八百四十七架次,擊落敵機(jī)五百二十九架,擊傷敵機(jī)一百一十架,炸毀敵機(jī)二百二十七架。同時
14、,中國空軍空戰(zhàn)中一共犧牲空勤人員六百六十一名。</p><p> 我至今仍然清楚的記得,在抗日戰(zhàn)爭即世界反法西斯戰(zhàn)爭勝利50周年的時候,我在一本描述抗戰(zhàn)空軍的書里第一次看到閻海文烈士那年青的面孔時所帶來的震撼,第一次看到高志航、沈崇海等空軍烈士的事跡時所帶來的感動,第一次聽說碧山空戰(zhàn)時的無奈。</p><p> 時至今日,已經(jīng)很少有人能夠記得在中國的天空獻(xiàn)身的抗日英雄們,我只能引用下面
15、這句話來表達(dá)我的心情:“你們的名字無人知曉,你們的業(yè)績與世長存! ”</p><p> 我的這款游戲取名為《覽橋風(fēng)光》,以紀(jì)念從覽橋中央航校走出的英雄們。</p><p><b> 1.5 本章小結(jié)</b></p><p> 引言和第一章中介紹了手機(jī)在無線應(yīng)用方向的當(dāng)今概況,J2ME的相關(guān)內(nèi)容,分析了J2ME在手機(jī)軟件開發(fā)中起的重要作用,
16、描述了本論文的相關(guān)背景。</p><p> 2 開發(fā)環(huán)境及相關(guān)技術(shù)的介紹</p><p><b> 2.1 開發(fā)環(huán)境</b></p><p> 操作系統(tǒng):Microsoft Windows XP</p><p> 程序語言:Java 2</p><p> 開 發(fā) 包:Java(TM)
17、 2 Standard Edition (5.0)</p><p> Sun Micro. J2ME Wireless Tool Kit 2.2</p><p> IDE: Eclipse 3.01</p><p> 2.2 Java語言特點(diǎn)</p><p><b> 1. 平臺無關(guān)性</b><
18、/p><p> Java引進(jìn)虛擬機(jī)原理,并運(yùn)行于虛擬機(jī),實(shí)現(xiàn)不同平臺之間的Java接口。Java的數(shù)據(jù)類型與機(jī)器無關(guān)。</p><p><b> 2. 安全性</b></p><p> Java的編程類似C++,但舍棄了C++的指針對存儲器地址的直接操作,程序運(yùn)行時,內(nèi)存由操作系統(tǒng)分配,這樣可以避免病毒通過指針入侵系統(tǒng)。它提供了安全管理器,防
19、止程序的非法訪問。</p><p><b> 3. 面向?qū)ο?lt;/b></p><p> Java吸收了C++面向?qū)ο蟮母拍?,將?shù)據(jù)封裝于類中,實(shí)現(xiàn)了程序的簡潔性和便于維護(hù)性,使程序代碼可以只需一次編譯就可反復(fù)利用。</p><p><b> 4. 分布式</b></p><p> Java建
20、立在TCP/IP網(wǎng)絡(luò)平臺上,提供了用HTTP和FTP協(xié)議傳送和接收信息的庫函數(shù),使用其相關(guān)技術(shù)可以十分方便的構(gòu)建分布式應(yīng)用系統(tǒng)。</p><p><b> 5. 健壯性</b></p><p> Java致力與檢查程序在編譯和運(yùn)行時的錯誤,并自動回收內(nèi)存,減少了內(nèi)存出錯的可能性。Java取消了C語言的結(jié)構(gòu)、指針、#define語句、多重繼承、goto語句、操作符、
21、重載等不易被掌握的特性,提供垃圾收集器自動回收不用的內(nèi)存空間。</p><p> 2.3 關(guān)于ECLIPSE</p><p> Eclipse 是一個開放源代碼的、基于 Java 的可擴(kuò)展開發(fā)平臺。就其本身而言,它只是一個框架和一組服務(wù),用于通過插件組件構(gòu)建開發(fā)環(huán)境。幸運(yùn)的是,Eclipse 附帶了一個標(biāo)準(zhǔn)的插件集,包括 Java 開發(fā)工具(Java Development Tool
22、s,JDT)。</p><p> 雖然大多數(shù)用戶很樂于將 Eclipse 當(dāng)作 Java IDE 來使用,但 Eclipse 的目標(biāo)不僅限于此。Eclipse 還包括插件開發(fā)環(huán)境(Plug-in Development Environment,PDE),這個組件主要針對希望擴(kuò)展 Eclipse 的軟件開發(fā)人員,因?yàn)樗试S他們構(gòu)建與 Eclipse 環(huán)境無縫集成的工具。由于 Eclipse 中的每樣?xùn)|西都是插件,
23、對于給 Eclipse 提供插件,以及給用戶提供一致和統(tǒng)一的集成開發(fā)環(huán)境而言,所有工具開發(fā)人員都具有同等的發(fā)揮場所。</p><p> 這種平等和一致性并不僅限于 Java 開發(fā)工具。盡管 Eclipse 是使用 Java 語言開發(fā)的,但它的用途并不限于 Java 語言;例如,支持諸如 C/C++、COBOL 和 Eiffel 等編程語言的插件已經(jīng)可用,或預(yù)計會推出。Eclipse 框架還可用來作為與軟件開發(fā)無
24、關(guān)的其他應(yīng)用程序類型的基礎(chǔ),比如內(nèi)容管理系統(tǒng)。Eclipse 是一個開放源代碼的、基于 Java 的可擴(kuò)展開發(fā)平臺。就其本身而言,它只是一個框架和一組服務(wù),用于通過插件組件構(gòu)建開發(fā)環(huán)境。</p><p> 2.4 關(guān)于Wireless Tool Kit</p><p> WTK(Wireless Tool Kit)是Sun公司針對J2ME推出的用于手機(jī)和Palm等移動設(shè)備的開發(fā)包,是除
25、手機(jī)廠商的專用開發(fā)包外唯一的手機(jī)模擬器開發(fā)包。它通用性高,開發(fā)出的應(yīng)用程序可保證能運(yùn)行在大部分設(shè)備上,而不像專用廠商具有一定的不兼容性。雖然它沒有強(qiáng)大的功能和完善的調(diào)試手段,但它提供運(yùn)行模擬器的最基本組件,是其他IDE需集成采用的必備元素。</p><p> 2.5 Java Appication Manager</p><p> 手機(jī)中負(fù)責(zé)調(diào)配程序運(yùn)行資源的管理后臺是Java App
26、lication Manager。它所使用的傳輸媒體可以是紅外線、網(wǎng)絡(luò)、以及其他可用來傳輸?shù)拿襟w。Java Application Manager 會從網(wǎng)絡(luò)上下載代表該Application Suite 的JAR 檔,接著在手機(jī)上安裝此MIDlet Suite,然后在手機(jī)開始執(zhí)行該應(yīng)用程序。</p><p><b> 2.6 本章小結(jié):</b></p><p>
27、第二章介紹了Java語言的特點(diǎn)、本程序的開發(fā)環(huán)境及其相關(guān)工具的原理和使用。</p><p> 3 程序結(jié)構(gòu)、思想和相關(guān)技術(shù)</p><p> 3.1 本程序需要解決的主要技術(shù)問題</p><p> 1. 游戲程序是一項精度要求很高的程序系統(tǒng),因?yàn)槠浯a利用率很高。一個實(shí)時運(yùn)行的最終作品,每秒都會運(yùn)行成千上萬行程序,繪圖事件、鍵盤事件都會以極高的頻率在后臺等
28、待響應(yīng),若有絲毫的差別都將很容易導(dǎo)致程序在運(yùn)行不久后可能出現(xiàn)嚴(yán)重錯誤,甚至死循環(huán)。因此,其邏輯設(shè)計應(yīng)當(dāng)相當(dāng)嚴(yán)謹(jǐn),需將所有可能發(fā)生的事件及意外情況考慮在設(shè)計中。</p><p> 2. 游戲中為了美觀,適用性強(qiáng),可能需要采用外部文件引入的圖片貼圖,有關(guān)貼圖,在MIDP2.0中提供了用于增強(qiáng)游戲功能的game包,使得解決靜態(tài)或動態(tài)、畫面背景、屏幕刷新的雙緩沖等都有較好的解決方案。</p><p
29、> 3. 玩家飛機(jī)的運(yùn)行可以通過鍵盤響應(yīng)事件控制,但敵方則因?yàn)槭亲詣舆\(yùn)行,就需要有一定的智能性;敵人飛機(jī)的運(yùn)行算法也要進(jìn)行相關(guān)的設(shè)置,已免游戲過于簡單。</p><p> 4.對于雙方發(fā)射的子彈應(yīng)該賦予不同的速度,同時,程序應(yīng)該設(shè)定敵人飛機(jī)的子彈不與敵人的飛機(jī)進(jìn)行碰撞檢測,已增加游戲的可玩性。</p><p> 5. 雙方的飛機(jī)在前進(jìn)時也需要考慮到是否碰撞到對方飛機(jī),以免重疊運(yùn)
30、行,造成許多物理上不可能的情況,缺乏真實(shí)感。每一次刷新頁面、每前進(jìn)一步都需要進(jìn)行相關(guān)的碰撞檢測。</p><p> 6.為了增加界面的美觀,在程序中添加了白云。由于手機(jī)屏幕大小有限,所以白云的數(shù)量和出現(xiàn)的位置要經(jīng)過相關(guān)的設(shè)置,才能實(shí)現(xiàn)白云不規(guī)則出現(xiàn)的效果。</p><p> 7. 游戲的地圖不可能通過繪圖來解決。否則,不僅難于控制和處理過多的元素,也會因過多的大型圖片而不能限制程序的
31、大小,失去手機(jī)上程序的原則和Java的優(yōu)勢。</p><p> 8. Java是基于虛擬機(jī)的半解釋型編譯系統(tǒng),其執(zhí)行效率較C++等完全編譯后的程序會低很多,程序如果不進(jìn)行精簡和優(yōu)化,將可能導(dǎo)致運(yùn)行的不流暢。除開發(fā)過程中對結(jié)構(gòu)上的控制、變量的使用、算法的優(yōu)化等優(yōu)化外,還可以使用混淆器(Obfuscator)進(jìn)行程序打包后的優(yōu)化。</p><p> 9. 游戲的結(jié)束、開始、動態(tài)信息畫面
32、作為構(gòu)成一個程序都是必不可少的重要部分。良好的用戶界面更是吸引用戶的硬指標(biāo),相關(guān)的美術(shù)構(gòu)圖和人性化設(shè)置也需要有一定的考慮。</p><p> 以上相關(guān)技術(shù)細(xì)節(jié)和整體流程將分別在以下小節(jié)闡述。</p><p><b> 3.2 程序流程</b></p><p> MIDlet suite是MIDP應(yīng)用程序的最小單位,JAM負(fù)責(zé)將手機(jī)內(nèi)的M
33、IDlet suite以圖形化的方式呈現(xiàn),讓用戶能夠選取欲執(zhí)行的MIDlet suite,一旦選取了某個MIDlet suite,操作系統(tǒng)就會激活KVM執(zhí)行里面的MIDlet。MIDlet及相關(guān)的支持類組成了MIDP應(yīng)用程序的實(shí)際內(nèi)容。而</p><p> 每個MIDlet都必須繼承javax.microedition.midlet.MIDlet這個抽象類。在MIDP規(guī)范中定義了MIDlet的生命周期,以及可以
34、存在的三種狀態(tài),包括Paused、Active以及Destroyed,每一個MIDlet在任何時刻只可能處于其中的一個狀態(tài)。這三種狀態(tài)的轉(zhuǎn)換關(guān)系如圖3-1所示:MIDlet有三個狀態(tài),分別是pause、active和destroyed。在啟動一個MIDlet的時</p><p> 候,應(yīng)用管理軟件會首先創(chuàng)建一個MIDlet實(shí)例并使得他處于pause狀態(tài),當(dāng)startApp()方法被調(diào)用的時候MIDlet進(jìn)入ac
35、tive狀態(tài),也就是所說的運(yùn)行狀態(tài)。在active狀態(tài)調(diào)用destroyApp(boolean unconditional)或者pauseApp()方法可以使得MIDlet進(jìn)入destroyed或者pause狀態(tài)。值得一提的是destroyApp(boolean unconditional)方法,事實(shí)上,當(dāng)destroyApp()方法被調(diào)用的時候,AMS通知MIDlet進(jìn)入destroyed狀態(tài)。在destroyed狀態(tài)的MIDlet必
36、須釋放了所有的資源,并且保存了數(shù)據(jù)。如果unconditional為false的時候,MIDlet可以在接到通知后拋出MIDletStateChangeException而保持在當(dāng)前狀態(tài),如果設(shè)置為true的話,則必須立即進(jìn)入destroyed狀態(tài)。</p><p> 本程序采用面向?qū)ο蟮脑O(shè)計模式,對游戲中的所有物體賦予對象的概念和屬性。運(yùn)行程序后允許用戶選擇執(zhí)行選項菜單,在開始游戲后將先從外部文件載入地圖文件
37、,對背景的所有物體進(jìn)行繪圖。在主程序運(yùn)行的線程中,畫面刷新將以一定的頻率采用雙緩沖技術(shù)對屏幕重繪,實(shí)時反映整個游戲的進(jìn)行狀態(tài)。</p><p> 游戲開始后先繪制地圖,并將各個對象實(shí)例化。在主程序運(yùn)行的線程中,游戲中所有的對象都應(yīng)該運(yùn)行在同一個線程下。當(dāng)敵人或者用戶的子彈達(dá)到射程范圍后,并不刪除子彈對象,而是使用setVisable(false)使其不能顯示,當(dāng)用戶或敵人在次發(fā)射子彈時,只需使用setVisab
38、le(true)設(shè)置成可以顯示即可。在屏幕重繪的主程序中,將在每次的循環(huán)中判斷若干事件,以便程序進(jìn)入相關(guān)的分支執(zhí)行相關(guān)的反應(yīng)代碼。如:玩家剩余飛機(jī)數(shù)是為0、敵人、玩家飛機(jī)是否被擊中、屏幕上相關(guān)信息的繪制等。</p><p> 程序?yàn)樾枰瓿瑟?dú)立功能的模塊設(shè)置了單獨(dú)的類。lzhhdm類繼承自Midlet,gameScrenn類、MenuScreen類繼承自GameCanvas,mybullets繼承自Sprite
39、類。載入程序后首先啟動的是程序介紹的信息畫面。點(diǎn)擊ok后調(diào)用MenuScreen類實(shí)現(xiàn)菜單。</p><p> 如果選擇進(jìn)入游戲,則調(diào)用gameScreen類,并且中止MenuScreen類中的線程運(yùn)行,已提高運(yùn)行速度。</p><p> Mybullets類為玩家子彈類。</p><p> 3.3 Canvas類</p><p>
40、為了能有程序開發(fā)人員控制接口的外觀和行為,需要使用大量的初級用戶接口類,尤其在游戲程序中,幾乎完全依賴的就是Canvas抽象類進(jìn)行繪圖。從程序開發(fā)的觀點(diǎn)看,Canvas類可與高級Screen類交互,程序可在需要時在Canvas中摻入高級類的組件。Canvas提供了鍵盤事件、指點(diǎn)桿事件(如果設(shè)備支持),并定義了允許將鍵盤按鍵映射為游戲控制鍵的函數(shù)。鍵盤事件由鍵代碼指定,但這樣控制游戲會導(dǎo)致缺乏通用性,并不是每個設(shè)備的鍵盤布局都適合游戲的操
41、作。應(yīng)當(dāng)將鍵代碼轉(zhuǎn)換為游戲鍵的代碼,以便硬件開發(fā)商能定義他們自己的游戲鍵布局。</p><p> 3.4 Graphics類</p><p> Graphics類提供了簡單的2D繪圖功能。它具有24位深度色彩的繪制能力,以三原色分別各占一個字節(jié)表示其顏色。程序只能在paint()函數(shù)中使用Graphics繪制,GameCanvas可調(diào)用getGraphics()函數(shù)直接繪制在緩沖區(qū)上,
42、可以在任何時間請求傳輸?shù)角芭_。其對象會被傳給Canvas的paint()函數(shù),以便最終顯示。</p><p> 3.5 MIDP1.0技術(shù)下的繪制背景技術(shù)</p><p> 在沒有MIDP2.0前,進(jìn)行游戲繪圖一般需要手動編程使用雙緩沖。需要在paint()方法內(nèi)將所想要畫的圖形畫在一張預(yù)先準(zhǔn)備好的背景上,等所有繪圖操作都完成后再將背景的數(shù)據(jù)拷貝到實(shí)際的屏幕上。Image類提供了一個建
43、立背景的靜態(tài)方法createImage(int width, int height),再利用getGraphics()方法取得屬于這個背景的Graphics對象,所進(jìn)行的繪圖操作都會作用在背景上,等到全部的繪圖操作完成后,再調(diào)用drawImage()方法將背景的數(shù)據(jù)復(fù)制到實(shí)際顯示的屏幕上。</p><p> 這樣的技術(shù)在繪制動畫時特別有用。繪制動畫時經(jīng)常需要不斷地更新畫面,而更新畫面的操作就是先將屏幕以fill
44、Rect()的方式清除,再將下一張圖片畫在屏幕上,然而反復(fù)的清除及重繪會造成屏幕的閃爍現(xiàn)象(flicker),因此使用雙重緩沖的好處就是在背景進(jìn)行這個清除及重繪的操作,再將完成的繪圖拷貝到屏幕上,由于用戶看不到清除的操作,因此就不會出現(xiàn)閃爍的現(xiàn)象了。不過在某些MIDP的實(shí)現(xiàn)上已經(jīng)加上了雙重緩沖的支持,因此在處理前應(yīng)先利用Canvas類的isDoubleBuffer()方法來判斷。</p><p> 3.6 MI
45、DP2.0新增的GameCanvas包</p><p> J2ME的流行促進(jìn)幾個運(yùn)營商和制造商開發(fā)了一些支持游戲的類,但是,這卻造成了游戲缺乏可移植性的問題,例如,很難將使用Siemens的Sprite類的游戲移植到Nokia上。</p><p> 在MIDP2.0版本發(fā)布后,這些游戲移植性問題初步得到了解決。MIDP2.0新加入了</p><p> Game
46、Canvas、Sprite、Layer、LayerManager、TiledLayer五個與游戲開發(fā)相關(guān)的類。其中 Layer類一般不會直接用到。</p><p> Game類的出現(xiàn)不僅降低了錯誤出現(xiàn)的幾率,也使游戲代碼變的更小,因?yàn)殚_發(fā)者不需要自己編寫象Sprite這種例子。下面將簡要介紹Game類。</p><p> GameCanvas類繼承自Canvas,所以具有Canvas所
47、具有的功能,還額外增加了一些便于游戲設(shè)計的功能。比如: GameCanvas類直接提供了getKeyStates(),使程序員可以在同一個線程自己偵測按鍵的狀態(tài)。GameCanvas類提供了flushGraphics()的功能,實(shí)現(xiàn)了雙緩沖技術(shù)。</p><p> 所謂的Sprite,就是畫面上獨(dú)立移動的圖形。</p><p> Sprite類是繼承自Layer的用于存儲多楨的基本可視
48、元素。不同的frame可交相顯示,構(gòu)成動態(tài)的效果。圖片可翻轉(zhuǎn)、顛倒、由一個主角圖片就可以方便的得到所有方向的顯示狀態(tài),相比原先只能使用Canvas繪圖,需要將所有方向的主角圖象都繪制在png圖象中簡化了許多。Sprite也可以從整合的圖象中讀圖,讀圖時將把大圖分解為若干等寬等高的小圖。每個小圖按照其排列順序有相應(yīng)的序號,在程序中調(diào)用其序號,就可以繪制出相應(yīng)的圖片。本程序中的雙方飛機(jī)、子彈、白云都由Sprite繼承得到。</p>
49、;<p> LayerManager提供控制整體畫面層的控制。它包括了一系列自動獲取了代號和位置的層,簡化了各層加入游戲畫面的過程,提供了自動排序和繪制的能力。</p><p> LayerManager存儲了一個層的列表,新的層可以用函數(shù)附加、刪除和插入。層的序號相當(dāng)于坐標(biāo)的Z軸,0層表示最接近用戶視覺,層數(shù)越高,離用戶越遠(yuǎn)。層號總是連續(xù)的,即使有中間的層被移除,其他層的序號會作相應(yīng)的調(diào)整以保
50、持整體的完整性。LM中的View Window控制著與LM相對坐標(biāo)的可視區(qū)域。改變View Window的位置可以制造出滾動屏幕的效果。</p><p> TiledLayer是有一組圖象格元素組成的整塊虛擬圖象。該類使不需要高分辨率的圖象就能創(chuàng)建大幅圖面成為可能。這項技術(shù)通常應(yīng)用在2D游戲平臺的滾動背景的繪圖。一塊整圖可被分割成等大小的圖象格,每塊格有其對應(yīng)的序號,按照行列遞增。多塊小格可由大塊同時替換組合而
51、模擬動態(tài)的背景,這不需要逐塊替換所有的靜態(tài)圖象格而顯得非常方便。</p><p> 3.7 PNG圖片格式</p><p> PNG(Portable Network Graphics)格式是MIDlet唯一支持的圖象格式,PNG具體格式由PNG Specification,Version 1.0定義的。PNG格式提供透明背景的圖象,這對繪制游戲畫面和被操縱主角極有幫助。飛機(jī)之間或與白
52、云碰撞時就不會因?yàn)楸尘坝刑囟ǖ念伾@示出的效果像貼上的圖片而缺乏真實(shí)感,物體之間輕微重疊時最上層圖片也不會覆蓋超過其有效象素外的部分。</p><p> PNG格式圖片中包含許多定義其圖片特性的冗余部分(Chunks)。這些代碼包含在每一個單獨(dú)的png格式圖象中,然而如果將多個png圖象合并在一張幅面稍大一些的整圖中,多個chunks就可以得到精簡,圖片的大小可以得到控制。使用Image類中的createIm
53、age函數(shù)可從整圖中分割出所需要的元素。在Game包中的TiledLayer和Sprite類都整合了這樣的功能。本程序中的地圖元素都集成在一張beijing.png圖片中,實(shí)現(xiàn)了方便的管理和程序體積的精簡。</p><p> 3.8 玩家飛機(jī)的控制方式和敵人方的智能運(yùn)行</p><p> GameCanvas提供getKeyStates函數(shù)可獲取當(dāng)前鍵盤上的信息。將以位的形式返回鍵盤上
54、所有鍵的按與釋放的狀態(tài),當(dāng)bit為1時,按鍵就是被按下的狀態(tài),為0時則為釋放狀態(tài)。只需要此一個函數(shù)的返回值就可以返回所有鍵的狀態(tài)。這保證了快速的按鍵和釋放也會被循環(huán)所捕捉。同時,這樣的機(jī)制也可檢測到幾個鍵同時按下的狀態(tài),從而提供斜向運(yùn)行等相應(yīng)功能(本程序沒有實(shí)現(xiàn)斜上運(yùn)行功能)。</p><p> 程序運(yùn)行時應(yīng)該對玩家飛機(jī)是否飛出屏幕的范圍進(jìn)行檢測,如果飛出屏幕,就應(yīng)該重新設(shè)定玩家飛機(jī)的位置。</p>
55、<p> 玩家飛機(jī)被擊中后,為了平衡游戲的可玩性,玩家飛機(jī)將有短暫時間無敵,即不進(jìn)行碰撞檢測,同時在屏幕右上角顯示無敵時間。</p><p> 根據(jù)游戲設(shè)定,敵人飛機(jī)。不能與玩家飛機(jī)重合,則他每走一步都需要檢測一下是否與玩家飛機(jī)碰撞。Sprite類中提供了collidesWith函數(shù),用于判斷是否與某個Sprite、TiledLayer、Image的對象有圖象上的重合(即游戲中的碰撞)。同理,還
56、需要檢測玩家子彈與敵機(jī)、敵機(jī)與玩家子彈是否碰撞。如果發(fā)生碰撞,將相關(guān)精靈圖片替換為爆炸圖片。</p><p> 敵人飛機(jī)需要具有一定的智能性,以便對玩家攻擊,使游戲具有一定的可玩性。敵人可以在適當(dāng)時候轉(zhuǎn)向或者開炮火,同時,程序應(yīng)該檢測敵機(jī)是否飛出了界外。</p><p> 在普通敵機(jī)中,有一組敵機(jī)的其中一架具有跟蹤功能,其原理為:當(dāng)其進(jìn)入屏幕后,根據(jù)玩家飛機(jī)的X、Y坐標(biāo)不斷調(diào)整自己的X
57、、Y坐標(biāo),已達(dá)成跟蹤的效果。由于線程的關(guān)系,敵機(jī)器的改變方向有時并不是實(shí)時的,這就可以使玩家有躲開撞擊的可能,增強(qiáng)了游戲的可玩性。</p><p> 在游戲進(jìn)行中出現(xiàn)的大型飛機(jī),由于其不可能立即被擊落,所以應(yīng)該設(shè)置其的運(yùn)行方法,理論上講還是根據(jù)玩家飛機(jī)的坐標(biāo),但是,在此設(shè)置一個標(biāo)志位,使得敵人在取的玩家位置后即開始玩家方向運(yùn)動,這期間,將不執(zhí)行取得玩家飛機(jī)位置重設(shè)飛行方向的步驟。這樣做,即防止了大飛機(jī)變成跟蹤飛
58、機(jī),又使得大飛機(jī)的運(yùn)行具有不確定性。</p><p> 在關(guān)尾出現(xiàn)的BOSS,其在屏幕上方左右移動并發(fā)射子彈。實(shí)際上,此時BOSS應(yīng)該通過玩家在游戲運(yùn)行中的習(xí)慣性的運(yùn)行方向,使用遺傳算法,來動態(tài)判斷玩家下一步的運(yùn)行方向,并且指揮普通飛機(jī)出現(xiàn)在預(yù)測的位置上??上в捎跁r間關(guān)系沒有實(shí)現(xiàn)。</p><p> 3.9 子彈的運(yùn)行和控制</p><p> 玩家的子彈是個精
59、靈數(shù)組,有9個元素,表示玩家一次最多可以發(fā)射3組9發(fā)子彈,對于一個完整的游戲來講,應(yīng)該根據(jù)關(guān)卡的不同而給予玩家不同的飛機(jī),飛機(jī)性能的差別在于子彈的射程不同。由于本游戲僅有一關(guān),所以子彈速度設(shè)定的差別沒有體現(xiàn)出來。</p><p> 當(dāng)玩家一次發(fā)射了3組子彈,而這3組子彈并沒有消失時,玩家將無法發(fā)射子彈。</p><p> 使用每組子彈的第一發(fā)作為與敵人進(jìn)行碰撞檢測的精靈,同時相關(guān)的標(biāo)志
60、位也設(shè)在第一發(fā)子彈中。如果玩家子彈與敵機(jī)相撞,則敵機(jī)消失時,子彈精靈的圖片替換為爆炸圖片,直到第二次發(fā)射該組子彈時,才將圖片替換為子彈圖片。</p><p> 3.10 內(nèi)存的優(yōu)化</p><p> 手機(jī)內(nèi)存空間小,所以在程序設(shè)計時應(yīng)該注意以下幾點(diǎn),以盡量減少內(nèi)存的使用:</p><p> (1)盡量縮短命名的長度。在應(yīng)用程序內(nèi),對于所建立的類、接口、方法及變
61、量名而言,都需要賦予一個識別的名稱,所命名的名稱每多一個字符就會在類文件內(nèi)多產(chǎn)生一個字節(jié),對于一個較復(fù)雜的應(yīng)用程序而言就會增加為數(shù)不小的數(shù)據(jù)量。所有這些可以借助混淆器來幫助實(shí)現(xiàn)</p><p> (2)所有代碼寫為一個類。</p><p> (3)只使用一個線程。</p><p> (4)盡量不使用靜態(tài)變量。</p><p> (5)
62、將PNG圖片合并成一張,減少圖形數(shù)據(jù)的大小。</p><p> 將PNG格式的小分辨率圖象合并在一張大的高分辨率圖象中,由于減少了頭文件的大小,將比合并前的總大小減少許多。</p><p> 3.11 內(nèi)存檢測器</p><p> Wireless Tool Kit提供了許多在運(yùn)行時監(jiān)視運(yùn)行狀態(tài)的工具。 包括內(nèi)存狀況的檢測(手機(jī)上的內(nèi)存空間十分有限,必須時刻關(guān)
63、注機(jī)載內(nèi)存是否大于程序所能使用到的最大可能的內(nèi)存空間),網(wǎng)絡(luò)狀況的檢測,運(yùn)行函數(shù)的跟蹤等。 內(nèi)存檢測器是內(nèi)存跟蹤測試隨時間變化的調(diào)試器。其中,允許強(qiáng)制垃圾回收(Garbage Collection)。由于Java語言中,不像許多其他的如C++語言,不需要指定回收函數(shù)中特定不使用的資源,資源回收機(jī)制將自動清空無效變量占用的空間。在程序運(yùn)行中也可以調(diào)用System類的gc()函數(shù)手動收回廢棄的內(nèi)存。</p><p>
64、 3.12 關(guān)于混淆器</p><p> Java 語言并沒有完全編譯成二進(jìn)制可執(zhí)行文件,編譯出的.class文件是一種介于源程序和二進(jìn)制之間的一中基于半解釋的字節(jié)碼,需要虛擬機(jī)來執(zhí)行。它包括了所有的信息。然而這樣會導(dǎo)致.class很容易被反編譯為源代碼,從而不能保護(hù)作者的知識成果。目前流行的如decode,JAD等反編譯工具可以以很快的速度生成源文件。如果不加以施行有效的措施,將造成嚴(yán)重的后果。</p
65、><p> 由此引入混淆器的概念?;煜鲗⒋a中的所有變量、函數(shù)、類的名稱變?yōu)楹喍痰挠⑽淖帜复?,如果缺乏相?yīng)的函數(shù)名指示和程序注釋,即使被反編譯,也將難以閱讀。</p><p> 混淆器的作用不僅僅是保護(hù)代碼,它也有精簡編譯后程序大小的作用。由于以上介紹的減少變量、函數(shù)的命名長度的關(guān)系,編譯后也會從.class文件中減少這些冗余的信息。混淆后,體積大約能減少25%,這對當(dāng)前費(fèi)用較貴的無線
66、網(wǎng)絡(luò)傳輸是有一定意義的。</p><p><b> 3.13 本章小結(jié)</b></p><p> 第三章中介紹了程序的流程、相關(guān)技術(shù)的思想及其在本程序中的應(yīng)用。對游戲基本算法等做了詳細(xì)敘述。具體算法的代碼實(shí)現(xiàn)和詳細(xì)流程將在下章介紹。</p><p> 4 程序分析和具體實(shí)現(xiàn)</p><p> 4.1 游戲進(jìn)入前
67、的選擇</p><p> 每個MIDlet程序都必須有一個主類,該類必須繼承自MIDlet。它控制著整個程序的運(yùn)行,并且可以通過相應(yīng)函數(shù)從程序描述文件中獲取相關(guān)的信息。該類中擁有可以管理程序的創(chuàng)建、開始、暫停(手機(jī)中很可能有正在運(yùn)行程序卻突然來電的情況,這時應(yīng)進(jìn)入暫停狀態(tài)。)、結(jié)束的函數(shù)。本程序主類為lzhhdm,并實(shí)現(xiàn)接口CommandLIstener。</p><p> 首先顯示的
68、是游戲的背景介紹(圖4-1),為此,在類lzhhdm定義Form類對象a,在startApp()函數(shù)中判斷isSplash是否為真,如果為真的話,將創(chuàng)建Form類的實(shí)例a,并且調(diào)用append()方法在表單上放置StringItem類的實(shí)例以顯示游戲背景信息。使用語句ok=new Command("ok",Command.OK,1);實(shí)例化Command類對象ok。調(diào)用addCommand()命令建立ok命令與Fo
69、rm之間的關(guān)聯(lián),調(diào)用setCommandListener()命令使Form與CommandListener建立關(guān)聯(lián)。調(diào)用Displayable的</p><p> seturrent()函數(shù)顯示背景介紹窗口。</p><p> 當(dāng)玩家點(diǎn)擊ok后將調(diào)用display.setCurrent(menuscreen)</p><p> 以顯示游戲菜單menuscre
70、en(圖4-2)。 </p><p> 類menuscreen繼承自Canvas類,并實(shí)現(xiàn)接口Runnable</p><p> 和CommandListener。在類menuscreen中定義了lowColor和</p><p> highColor、highBGColor三個整型變量及布爾型變量co。其</p><p> 中l(wèi)o
71、wColor賦值為0x000000FF,代表蘭色,higColor賦值為</p><p> 0x00FF0000,代表紅色,highBGColor賦值為0x00CCCCCC,代表</p><p> 蘭灰色,即背景條。當(dāng)玩家按住上或下鍵時,在函數(shù)keyPressed</p><p> (int code)中的整型變量menuIndex相應(yīng)的減1或加1,相應(yīng)的,在
72、paint()函數(shù)中會根據(jù)menuIndex繪制選項是否被選中。在函數(shù)run()中,如果co為真,則不停的repaint(),設(shè)置co的意義在于,當(dāng)進(jìn)入游戲主畫面后,co賦值為false,以終止繪制選項的repaint(),提高游戲速度。 </p><p> 當(dāng)移動選項條到某項,并點(diǎn)擊ok時,在commandAction()方法中
73、根據(jù) menuIndex </p><p> 的值判斷選擇了哪個選項,列如當(dāng)選擇“關(guān)于”時,將調(diào)用lzhhdm類中的renwuShow()方法以顯示”關(guān)于”界面(圖4-3),在renwuShow()方法中,F(xiàn)orm類對象a=null,表示清空Form,并重新調(diào)用用append()方法在表單上放置S
74、tringItem類的實(shí)例以顯示游戲關(guān)于信息,“幫助“界面的顯示與”關(guān)于“界面相同,只不過調(diào)用的是helpShow()方法。</p><p> 4.2 mybullets類 </p><p> 在介紹游戲主類gameScreen類之前,應(yīng)該先簡要說明一下玩家子彈類mybullets類,實(shí)際上,mybullets類是應(yīng)該刪除的,其要實(shí)現(xiàn)的功能應(yīng)該放在gameScreen類中,但是由于
75、設(shè)計游戲的過程也是一個學(xué)習(xí)的過程,而在當(dāng)時,我并沒有意識到這一點(diǎn)。 </p><p> Mybullets類繼承自Sprite類,以實(shí)現(xiàn)玩家子彈的相關(guān)功能。首先,創(chuàng)建子彈狀態(tài)數(shù)組private int[][] bullets,其中,[i][0]代表子彈的X坐標(biāo),[i][1]代表子彈的Y坐標(biāo),[i][2]代表子彈Y方向速度,[i
76、][3]代表子彈存活狀態(tài)(由于此類是在早期設(shè)計的,而之后子彈存活狀態(tài)使用了子彈射程作為標(biāo)志位,所以其并沒有起到作用)。類中定義的方法setfirstposition()起到定義玩家子彈發(fā)射坐標(biāo)的作用(此方法在設(shè)計時起到的作用是消除每按一次開火玩家子彈位置就重新定位這個BUG,但是,這個BUG完全可以用設(shè)置標(biāo)志位的方法消除)。方法newposition()實(shí)現(xiàn)的功能為更新玩家的子彈位置,并且檢測玩家子彈與普通敵人的碰撞及記錄玩家戰(zhàn)果(更新
77、子彈位置的功能可以由使用move()加設(shè)置標(biāo)志位的方法取代;由于設(shè)計這個類的時候并沒有考慮到添加BOSS等,所以在此檢測碰撞,但添加BOOS等功能后,此處的檢測完全可以和飛機(jī)對飛機(jī)等的碰撞檢測封裝在同一個方法中)。</p><p> mybullets類在gameScreen中建立了對象數(shù)組huokebullet[9],代表玩家所能發(fā)射的9發(fā)子彈。</p><p> 4.3 游戲邏輯及
78、gameScreen類</p><p> gameScreen類是游戲的主類,決定著敵人何時出現(xiàn),控制著敵人出現(xiàn)的方法,判斷敵人及玩家是否被擊中等。它運(yùn)行在獨(dú)立的線程中,以恒定的頻率刷新畫面。本程序設(shè)置為1/20秒。其主邏輯如圖4-4所示。 </p><p> 4.3.1 gameScreen類所實(shí)現(xiàn)的功能</p><p> gameScreen類要
79、實(shí)現(xiàn)地圖的滾動、敵人飛機(jī)的相關(guān)屬性、玩家的相關(guān)屬性等功能。</p><p> gameScreen類包括了LayerManager,這樣所有靜態(tài)和動態(tài)的圖象都不需要手動刷新,只需要在LayerManager中加入所有的需要控制的精靈,在統(tǒng)一由LayerManager刷新即可, 因此,在gameScreen中創(chuàng)建LayerManager的對象lm,并在構(gòu)造函數(shù)中實(shí)例子化。</p><p>
80、 其他精靈類的對象如敵人飛機(jī)、玩家飛機(jī)、玩家飛機(jī)的子彈、敵人的子彈、BOSS及BOSS所屬的子彈都需在gameScreen()類中建立相應(yīng)的對象,并在構(gòu)造喊數(shù)中實(shí)例化,且由lm.appned()方法添加到LayerManager類對象lm中。</p><p> 4.3.2 地圖的創(chuàng)建</p><p> 由于手機(jī)存儲空間的限制,不可能將整張地圖完整地存儲在手機(jī)中,為了節(jié)約空間,往往提出
81、地圖中相同的圖片組成一張PNG格式的圖片,然后象拼圖一樣拼出地圖來,專業(yè)的游戲設(shè)計者往往自己寫一個地圖編輯器,以使拼圖過程不是那么痛苦。 </p><p> 創(chuàng)建地圖就需要使用TiledLayer。TiledLayer指的是由一塊一塊類似用瓷磚拼湊起來的畫面。地圖實(shí)際即為TiledLayer的一個對象。先利用TiledLayer的構(gòu)造函數(shù)建立TiledLayer,根據(jù)構(gòu)造函數(shù)的參數(shù)可以給定Cell數(shù)組 的大小,
82、并且地圖圖片切割成等尺寸的畫面,并調(diào)用setCell()設(shè)置具體的圖象格內(nèi)容。地圖</p><p> 圖片如圖4-5所示。</p><p> 因此,創(chuàng)建一個返回TtiledLayer的方法createBackGround(),以便在gameScreen()的構(gòu)造函數(shù)中調(diào)用。在方法中,定義整型數(shù)組map1[]以存儲Cell的索引值。并使用tiledLayer.setCell(column
83、,row,map1[i])設(shè)定TtiledLayer的內(nèi)容,以形成地圖。其中i的值由循環(huán)for(int i=0;i<map1.length;i++)取得,column由語句column=i%15取得、行由row=(i-column)/15取得。</p><p> 畫出地圖后,由lm.append()將地圖添加到LayerManager類對象lm中。由于地圖位于Layer的最低層,即離用戶視線最遠(yuǎn)的層,所以
84、Tiledlayer最后一個被添加到lm中。</p><p> 4.3.3地圖的移動 </p><p> 根據(jù)游戲的設(shè)定,游戲中地圖是向下移動的,實(shí)現(xiàn)此功能的方法如下:</p><p> 首先,在使用createBackGround()函數(shù)創(chuàng)建地圖數(shù)組時,用(row+1)*16-getHeight()
85、 </p><p> 語句對整型變量row2賦值,其中row+1代表地圖有多少列,16為地圖片的高度,而減去getHeight()是因?yàn)橐舫鲆粋€屏幕的可視區(qū)域,由于J2ME規(guī)定坐標(biāo)系中下方向?yàn)檎?,所以使用語句y1=-row2將row2的數(shù)值變?yōu)樨?fù)數(shù)。</p><p> 其次,render()函數(shù)中,使用lm.setViewWindow(0
86、,0,getWidth(),getHeight()+10000)設(shè)定可視區(qū)域的范圍,(0,0)表示View Window的起始坐標(biāo),(getWidth() ,getHeight()+10000) </p><p> 使用lm.paint(g,0,y1)決定</p><p> View Window從屏幕的哪里畫起。</p><p> 在run()函數(shù)中的w
87、hile(conti)中,</p><p> 使用語句y1=y1+1使得每次繪圖都使</p><p> 地圖下移1個象素。(參考圖4-6)</p><p> 4.3.4 gameScreen類的構(gòu)造函數(shù)</p><p> gameScreen類的構(gòu)造函數(shù)要將游戲中出現(xiàn)的所有精靈都實(shí)例化,實(shí)際上,這種方法</p><
88、p> 嚴(yán)重的占用了內(nèi)存,但在當(dāng)時,我并沒有意識到這一點(diǎn)。</p><p> 由于敵人要求不停的出現(xiàn),但是不可能設(shè)置過多的精靈,解決的辦法是設(shè)定6個Sprite類對象j0、j1、j2及jbullet1、jbullet1、jbullet2,分別代表三架敵機(jī)及其配屬的子彈。所以在gameScreen類的構(gòu)造函數(shù)分配這6個Sprite類的存儲空間,并且使用new Sprite(Image img, int wi
89、dth,int height)實(shí)例化這6個類變量。同關(guān)尾cboss與游戲進(jìn)行中的大飛機(jī)其他的Sprite類對象都需要使用相同的方法實(shí)例化。同樣處于節(jié)約內(nèi)存的考慮,sboss與cboss同用3個Sprite類對象bossbullet0,1,2。</p><p> 在構(gòu)造函數(shù)中,定義boolean型變量conti=true。conti的作用在于控制是否進(jìn)行游戲畫面的重繪及其他需要在畫面重繪前進(jìn)行的運(yùn)算。</p
90、><p> 在構(gòu)造函數(shù)中,將mybullets類里的no和score初始化,現(xiàn)在看來no的初始化沒有必要,但是score的初始化是必須的,因?yàn)檫@個變量存儲著玩家每次游戲的成績,如果不在此進(jìn)行初始化,則玩家重新開始游戲后score并不歸0。</p><p> 4.3.5 關(guān)于commandAction()方法</p><p> 每個創(chuàng)建Command實(shí)例的J2ME的
91、應(yīng)用程序也必須創(chuàng)建實(shí)現(xiàn)CommandListener接口的實(shí)例。每當(dāng)用戶通過commandAction()方法的方式與命令進(jìn)行交互的時候,就會通過CommandLIstener.所以實(shí)現(xiàn)CommandListener的類必須實(shí)現(xiàn)commandAction()方法。</p><p> 在commandAction()方法中,使用getabel()方法獲取命令的標(biāo)簽。如果getLabel()=“暫停”時,表示玩家點(diǎn)
92、擊了暫停鍵,此時,conti賦值為false,游戲畫面的繪制及游戲相關(guān)的運(yùn)算暫停,并且,使用removeCommand(c)語句將“暫停”移除,使用addCommand(new Command("繼續(xù)",Command.OK,2));將”繼續(xù)“按紐”添加進(jìn)來。當(dāng)玩家點(diǎn)擊“繼續(xù)“時,conti賦值為true,并且,一定要調(diào)用start()方法,否則繼續(xù)功能不可用。必須調(diào)用start()方法的原因是:J2ME的線程已st
93、op()方法拿掉,如果想停止線程的運(yùn)做,就必須依靠一個旗標(biāo)(flag),在本程序中,flag就是boolean型變量conti。所以一旦此標(biāo)識變量被設(shè)為false,那么while(conti)循環(huán)就會結(jié)束,線程也會跟著結(jié)束。當(dāng)用戶按下“繼續(xù)”的時候,start()將重新產(chǎn)生一個線程繼續(xù)執(zhí)行相關(guān)的運(yùn)算和畫面繪制。</p><p> 當(dāng)玩家通關(guān)時或者任務(wù)失敗時,將顯示相應(yīng)信息,并使用上面的方法將“暫?!辨I變?yōu)椤胺祷?/p>
94、”鍵盤,當(dāng)點(diǎn)擊“返回”鍵時,將返回主菜單選項,調(diào)用類lzhhdm里的方法menuscreensecond(),在此方法中,實(shí)例化一個MenuScreen類對象,并且使選項“新游戲”改變?yōu)椤敝匦麻_始“(圖4-7)。完成此項功能的語句子為MenuScreen.mainmenu[0] =”重新開始”。當(dāng)選擇”重新開始“時,使用gamescreen=new gameScreen(this)將使所有變量重新被初始化,如地圖的繪制、敵人出現(xiàn)位置的重
95、置、敵人的數(shù)量、玩家飛機(jī)的當(dāng)前位置等。使用gamescreen.start()重新開始程序的循環(huán)。</p><p> 4.3.6 Sprite類對象的碰撞檢測及相關(guān)屬性</p><p> 游戲進(jìn)行中,即在while(conti){ }中,需要進(jìn)行玩家飛</p><p> 機(jī)、子彈與敵機(jī)及敵機(jī)子彈與玩家飛機(jī)的碰撞檢測,即使用函</p><p&
96、gt; 數(shù)collidesWith(Sprite,boolean)。由于設(shè)計的問題,玩家發(fā)</p><p> 射的子彈與普通敵機(jī)的碰撞檢測被寫在了mybullets類中,并</p><p> 且只檢測第一發(fā)子彈是否與敵人相碰撞,如果碰撞為真時,則</p><p> 使用setVisible(false)函數(shù)將敵機(jī)隱藏,使用setImage()函</p&
97、gt;<p> 數(shù)將子彈精靈的三張圖片置換為爆炸圖片( 圖4-8 )。當(dāng)敵人剩</p><p> 余飛機(jī)消失后,即所有的敵人都飛出了屏幕后,使用函數(shù)</p><p> setVisible(true)將敵機(jī)重新設(shè)置為可見。在按“開火”鍵時,使用setImage()函數(shù)將huokebullets重新設(shè)定為子彈圖片(每次擊落敵機(jī)后屏幕上的爆炸效果有3團(tuán),并且按“開火”后爆炸
98、圖片就消失了,實(shí)際上setVisavle(false)的應(yīng)該是子彈數(shù)組,而對敵人精靈使用setImage(),這樣效果會好一些)。</p><p> 敵機(jī)與玩家的碰撞檢測原理同上,都是使用的collidesWith()函數(shù),遺憾的是,我在寫這段代碼的時候,并沒有考慮設(shè)置玩家有4次機(jī)會,所以對敵人飛機(jī)setVisable(fasle)了,而將玩家的飛機(jī)換成了爆炸圖片,之后,添加了玩家4次機(jī)會這個功能,由于玩家被擊
99、落后會重新從屏幕下方進(jìn)入屏幕,所以爆炸的圖片一閃而過,效果不是很好。</p><p> 4.3.7 玩家4次游戲機(jī)會的實(shí)現(xiàn)方法</p><p> 根據(jù)游戲設(shè)置,玩家在每關(guān)中有共四次機(jī)會,當(dāng)玩家飛機(jī)被擊中或撞擊爆炸后,程序首先檢測整型變量playerno的值,并根據(jù)playerno的值決定屏幕右上角所畫玩家飛機(jī)標(biāo)志的數(shù)量(參考圖4-8),playerno的初始值設(shè)為3,因?yàn)榕鲎埠蟛艤p1
100、,所以玩家共有4次機(jī)會,當(dāng)playerno<0時,游戲結(jié)束,同時將變量pver賦值為1,render()或renderboss()函數(shù)中,over=1代表在屏幕上GAMEOVER等相關(guān)信息,同時,將整型變量inputno賦植為1,以使手機(jī)的方向鍵失效,以消除玩家可以控制爆炸圖像移動這個BUG。同時整型變量pzbz賦植為1,以消除玩家爆炸圖像繼續(xù)與敵人進(jìn)行碰撞檢測這個BUG。</p><p> 當(dāng)playe
101、rno>0時,碰撞后,將變量planert賦值為1,在之后的if(planert==1)判斷語句中,重新設(shè)定玩家飛機(jī)的圖片和可視狀態(tài),同時使用setPosition()函數(shù)設(shè)定玩家非的位置在屏幕下方。設(shè)定pzbz=1,即不檢測碰撞,玩家有短暫時間無敵,無敵時間由屏幕右上角進(jìn)度條表示。設(shè)定inputno=1,即飛入屏幕的過程中手機(jī)鍵盤是不可以用的。設(shè)置planert=2,即以上這些設(shè)置只執(zhí)行一便。</p><p&
102、gt; 在if(planert==2)判斷語句中,使用語句move(</p><p> 0,-2)使飛機(jī)自己向上運(yùn)動,使用if(c1.getY()<(</p><p> planepo-24))判斷飛機(jī)是否到達(dá)屏幕最下方(planepo</p><p> 是屏幕下邊緣的坐標(biāo)),如條件為真,則將inputno</p><p>
103、設(shè)置為1,表示鍵盤可用,將planert賦值為3,使</p><p> 其不再執(zhí)行以上各步。</p><p> 4.3.8 input() </p><p> input()函數(shù)的作用是檢測用戶的輸入。</p><p> 首先使用if(inputno==0)判斷用戶的輸入是否</p><p> 被禁止,如為真
104、,則用戶輸入不被禁止。</p><p> 其次,調(diào)用getKeyStates()查詢按鍵的狀態(tài)。</p><p> 當(dāng)玩家按方向鍵時,玩家飛機(jī)就向不同的方向運(yùn)行,這需要使用c1.move(int x,int y)函數(shù),當(dāng)玩家控制飛機(jī)向左或右飛時,需要使c1.setFrame()函數(shù)改變飛機(jī)的圖形(參見圖4-7,此時飛機(jī)右飛)。同時,還需要判斷飛機(jī)是否飛出屏幕,如,當(dāng)飛機(jī)右飛時,用if(
105、c1.getX()>(getWidth()-c1.getWidth()))</p><p> 語句判斷(getWith()為屏幕的寬度,c1.getWidth()為玩家飛機(jī)c1的寬度),如果條件為真,則使用c1.setPosition((getWidth()-c1.getWidth()),c1.getY())語句將飛機(jī)設(shè)置在緊靠屏幕右邊的位置。上、下、左的設(shè)置原理同上。</p><p&
溫馨提示
- 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
- 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
- 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內(nèi)容里面會有圖紙預(yù)覽,若沒有圖紙預(yù)覽就沒有圖紙。
- 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
- 5. 眾賞文庫僅提供信息存儲空間,僅對用戶上傳內(nèi)容的表現(xiàn)方式做保護(hù)處理,對用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對任何下載內(nèi)容負(fù)責(zé)。
- 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請與我們聯(lián)系,我們立即糾正。
- 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時也不承擔(dān)用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。
最新文檔
- 畢業(yè)設(shè)計--基于java的游戲設(shè)計
- 基于java手機(jī)游戲畢業(yè)設(shè)計
- 畢業(yè)設(shè)計論文 java 24點(diǎn)游戲設(shè)計
- JAVA打飛機(jī)游戲畢業(yè)設(shè)計.doc
- -java-打飛機(jī)游戲畢業(yè)設(shè)計
- JAVA打飛機(jī)游戲畢業(yè)設(shè)計.doc
- 畢業(yè)設(shè)計---俄羅斯方塊游戲java
- [畢業(yè)設(shè)計資料]連連看java小游戲畢業(yè)設(shè)計資料
- 畢業(yè)設(shè)計---java編寫的坦克大戰(zhàn)的游戲設(shè)計
- 畢業(yè)設(shè)計(論文)+手機(jī)游戲開發(fā)-java畢業(yè)論文
- java打飛機(jī)游戲畢業(yè)設(shè)計(源代碼+論文)
- 連連看java小游戲畢業(yè)設(shè)計論文
- java_掃雷游戲課程設(shè)計與實(shí)現(xiàn)畢業(yè)設(shè)計
- 基于java的掃雷游戲的設(shè)計與實(shí)現(xiàn)畢業(yè)設(shè)計
- 掃雷畢業(yè)設(shè)計---基于java掃雷游戲的設(shè)計與實(shí)現(xiàn)
- java貪吃蛇游戲畢業(yè)設(shè)計(源代碼+論文)
- 畢業(yè)設(shè)計---基于j2me的java游戲
- jsj04-004@java打飛機(jī)游戲畢業(yè)設(shè)計
- 畢業(yè)設(shè)計---基于java的網(wǎng)絡(luò)版坦克大戰(zhàn)游戲設(shè)計
- jsj04-004@java打飛機(jī)游戲畢業(yè)設(shè)計
評論
0/150
提交評論