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