JAVA入門 基于Java的移動(dòng)游戲開發(fā)
如果讀者有Java編程經(jīng)驗(yàn),尤其是AWT和SWING的Java GUI開發(fā)經(jīng)驗(yàn)將十分有助于理解本文,盡管不是必需的。
一、 引言
近來(lái),移動(dòng)游戲在提供個(gè)人娛樂方面變得越來(lái)越流行。這種流行使得移動(dòng)游戲給手機(jī)用戶,游戲出版商和手持設(shè)備制造者帶來(lái)豐厚的利潤(rùn);移動(dòng)游戲,在給游戲開發(fā)者和相關(guān)人員帶來(lái)無(wú)數(shù)商機(jī)的同時(shí),處于極為重要的樞紐位置。據(jù)估計(jì),到2009年,全世界的手機(jī)玩家有望達(dá)到兩億兩千萬(wàn)之多,移動(dòng)游戲業(yè)將被規(guī)劃并擴(kuò)展到一個(gè)更高層次,為手機(jī)用戶和手持設(shè)備制造者帶來(lái)更大的利潤(rùn)份額。
移動(dòng)游戲可以分為三大類:
1、嵌入式游戲:被硬編碼到移動(dòng)手持設(shè)備系統(tǒng)中的游戲,并隨著設(shè)備一同發(fā)布。不久就會(huì)過(guò)時(shí)。例如:隨著諾基亞手機(jī)一同發(fā)行的貪吃蛇游戲。
2、SMS游戲:通過(guò)發(fā)送文本消息來(lái)玩的游戲-例如,把SMS消息發(fā)送到游戲服務(wù)器-該服務(wù)器處理這些SMS消息,然后再通過(guò)SMS消息形式發(fā)送回結(jié)果。經(jīng)常是以在線競(jìng)賽和測(cè)驗(yàn)形式出現(xiàn)。并不很流行,因?yàn)橛螒虻馁M(fèi)用將隨著把每一個(gè)SMS發(fā)送到游戲服務(wù)器而逐步增加。
3、瀏覽器游戲:這些游戲可以使用移動(dòng)電話的內(nèi)嵌微型瀏覽器(專用于移動(dòng)設(shè)備的網(wǎng)絡(luò)瀏覽器)來(lái)玩,在線或離線的方式都可以。玩家可以通過(guò)自己的手持設(shè)備或一個(gè)第三方游戲供給者的游戲Web站點(diǎn)的方式在線玩這樣的游戲,或下載它們后離線玩。這一類游戲又有很多種類,例如單人或者多人游戲,網(wǎng)絡(luò)游戲,離線游戲,街機(jī)游戲,等等。
在這三種類型中,瀏覽器游戲是今天最流行的移動(dòng)游戲類型,這是因?yàn)樗鼈兙哂袆?chuàng)新性和豐富的多媒體內(nèi)容,引人入勝的表達(dá)與SMS游戲相比的低價(jià)位優(yōu)勢(shì)。本文將重點(diǎn)討論瀏覽器游戲開發(fā)。今后,術(shù)語(yǔ)"移動(dòng)游戲"在本文專指"瀏覽器游戲"。
注意:本文集中于討論2D游戲開發(fā)。因?yàn)榻裉炝餍械拇蟛糠值臄?shù)字移動(dòng)電話有很有限的資源(小的屏幕,有限的內(nèi)存和圖形支持,繁瑣的鍵盤輸入),所以時(shí)下最適合于這些設(shè)備的也是最具有商業(yè)可行性的游戲是2D游戲。但是,隨著移動(dòng)電話能力的不斷提高,3D游戲在不久的將來(lái)將廣為流行。
移動(dòng)游戲可用C++,Java(J2ME),還有Qualcomm公司的Binary Runtime Environment for Wireless(BREW)平臺(tái)來(lái)進(jìn)行開發(fā)。
二、 為什么選擇Java進(jìn)行移動(dòng)游戲開發(fā)?
盡管C++能夠被編譯成本機(jī)代碼并且可以直接存取本機(jī)系統(tǒng)資源,以及與BREW(它允許開發(fā)者使用任何希望的語(yǔ)言,包括C++,Java,XML和Flash)相結(jié)合為移動(dòng)游戲開發(fā)者提供端到端的解決方案,但是Java仍然是進(jìn)行移動(dòng)游戲開發(fā)的最流行的選擇。Java,或更精確的說(shuō)是Java 2微型版本(J2ME)平臺(tái),被認(rèn)為是開發(fā)移動(dòng)游戲的最方便的語(yǔ)言。(要更多地了解J2ME,請(qǐng)參考"What is Java 2 Micro Edition?")。J2ME如此流行的背后動(dòng)力包括:
- J2ME遵循為大多數(shù)手持設(shè)備生產(chǎn)商所支持的工業(yè)標(biāo)準(zhǔn),如今大多數(shù)的移動(dòng)電話都支持Java開發(fā)。
- J2ME是一個(gè)自由的和開放的平臺(tái)。這使得開發(fā)人員投資很少,但卻提供給他們必需的靈活性以及大量的支持。
- 它的高度可移植的特性("書寫一次到處運(yùn)行")保證一部為一個(gè)品牌/類型的手持設(shè)備開發(fā)的游戲應(yīng)用程序,將可以工作在其它類型的支持Java的手持設(shè)備品牌/類型上。
- 它特別為小型設(shè)備進(jìn)行了優(yōu)化,是輕量級(jí)的,高度安全的,因?yàn)樵谄渖祥_發(fā)的應(yīng)用程序不能存取或者影響運(yùn)行在該手持設(shè)備上的其它應(yīng)用程序。
- J2ME包含移動(dòng)信息設(shè)備輪廓(MIDP)API,它的設(shè)計(jì)是為專門開發(fā)包括手機(jī)在內(nèi)的移動(dòng)設(shè)備應(yīng)用程序,但切記它們的局限性和約束條件。而且,最新的MIDP 2.0版自己提供了一套完整的API以用于游戲開發(fā),這使得游戲開發(fā)更為簡(jiǎn)單和快捷。
現(xiàn)在,我們探索一下MIDP 2.0在移動(dòng)游戲開發(fā)環(huán)境中的使用。
三、 MIDP2.0在游戲開發(fā)中的地位
MIDP2.0 API是一組具有特別性能的API,可用于開發(fā)安全的,內(nèi)容豐富的多媒體應(yīng)用軟件,包括適合于移動(dòng)設(shè)備的游戲程序。MIDP 2.0基于以前的MIDP 1.0之上并提供一個(gè)更好的開發(fā)平臺(tái)以創(chuàng)建高效快速的移動(dòng)設(shè)備應(yīng)用程序。
MIDP 2.0進(jìn)一步提煉了MIDP 1.0的特性和有關(guān)功能。有關(guān)這些新特性的信息請(qǐng)參考What’s New in MIDP 2.0。新增添到MIDP上的重要特點(diǎn)之一是Game API,或更精確地說(shuō)是javax.microedition.lcdui.game API包。通過(guò)該Game API,MIDP 2.0提供給游戲開發(fā)者現(xiàn)成的程序模塊,這些模塊在早期的MIDP 1.0時(shí)是你必須從頭開始創(chuàng)建的。這些模塊以類的形式提供,用于創(chuàng)建和控制各種游戲元素,如游戲畫布、精靈、層等等(后文將介紹)。這樣,MIDP 2.0大大減少了游戲開發(fā)者的創(chuàng)作時(shí)間。
進(jìn)行游戲開發(fā)必需的另外兩個(gè)MIDP 2.0 API包,在本文中也作了探索,它們是javax.microedition.midlet和javax.microedition.lcdui。
javax.microedition.midlet API包是開發(fā)各種類型的移動(dòng)應(yīng)用程序的基礎(chǔ)。它包含javax.microedition.midlet.MIDlet類,它是所有的基于J2ME的移動(dòng)應(yīng)用軟件(或稱為midlet)的基類,它必須由所有移動(dòng)應(yīng)用程序的main類加以擴(kuò)展后使用。非常類似于java.applet.Applet類,MIDlet類提供創(chuàng)建midlet程序的必要的資源。
javax.microedition.lcdui API包是開發(fā)各種類型的移動(dòng)應(yīng)用程序的用戶接口所必需的。這個(gè)API提供類來(lái)創(chuàng)建和控制UI部件(例如屏幕,表單,文本框,單選按鈕,等等)并且處理包括游戲在內(nèi)的移動(dòng)應(yīng)用程序的輸入。有使用AWT和SWING GUI開發(fā)經(jīng)驗(yàn)的開發(fā)者會(huì)發(fā)現(xiàn)javax.microedition.lcdui包中的元素非常相似于這些API中的元素。
我將在本文的示例游戲開發(fā)期間討論這些API中的和游戲開發(fā)相關(guān)的元素。
#p#
四、 構(gòu)建示例游戲
為了更好地理解這些API和它們各自的類,你最好動(dòng)手開發(fā)一個(gè)簡(jiǎn)單的移動(dòng)游戲。這里是一個(gè)單人的離線游戲,通過(guò)障礙物線路的駕車游戲。玩家使用左鍵和右鍵用于改變車的方向到左邊或者右邊以防止與障礙物的碰撞。游戲在發(fā)生碰撞并顯示得分后結(jié)束。該游戲命名為HardDrive。
注意:雖然這個(gè)示例游戲是使用J2ME Wireless Toolkit 2.1_01和J2SE 1.4.2_07 SDK在Windows 2000平臺(tái)上開發(fā)的,但是,其它版本的與另外一些平臺(tái)相匹配的Wireless Toolkit和J2SE SDK也可以利用。
現(xiàn)在開始構(gòu)建游戲程序HardDrive。從前一節(jié)中得知,你第一個(gè)需要開發(fā)的程序是HardDriveMIDlet(HardDriveMIDlet.java),它擴(kuò)展了javax.microedition.midlet.MIDlet類。
(一) HardDriveMIDlet.java
列表1.1:該代碼片斷來(lái)自于文件HardDriveMIDlet.java
- import javax.microedition.midlet.MIDlet;
- import javax.microedition.lcdui.*;
- public class HardDriveMIDlet extends MIDlet implements CommandListener {
- ... ... ... ... ... ... ... ...
HardDriveMIDlet還實(shí)現(xiàn)了javax.microedition.lcdui.CommandListener接口來(lái)接收命令事件,它們是在應(yīng)用程序執(zhí)行和處理期間產(chǎn)生的。當(dāng)發(fā)出EXIT,CANCEL,BACK,OK,STOP以及類似的命令-這些命令通過(guò)使用軟按鈕(在移動(dòng)電話屏幕附近的特殊的按鈕,除了箭頭鍵以外)產(chǎn)生并被HardDriveMIDlet的commandAction()方法所處理-時(shí),這些命令事件發(fā)生。為了提高效率,可把這些命令添加到畫布上去。
HardDriveMIDlet用作所有canvas的容器,這些canvas是一些描述可用于在移動(dòng)設(shè)備屏幕上進(jìn)行繪制的對(duì)象。這里,midlet包含了HardDriveCanvas,它擴(kuò)展了javax.microedition.lcdui.game.GameCanvas類。GameCanvas是一個(gè)專門的畫布,用于為游戲程序繪制有效的動(dòng)畫圖像,還能夠查詢?yōu)閷?shí)現(xiàn)平滑動(dòng)畫效果而采取的脫屏圖像緩沖技術(shù)有關(guān)的關(guān)鍵狀態(tài)。
HardDriveMIDlet包含的另外的一個(gè)canvas是GameOverCanvas,它擴(kuò)展了javax.microedition.lcdui.Canvas類。Canvas是一個(gè)簡(jiǎn)單canvas,用于繪制文本,線段以及簡(jiǎn)單的形狀等。當(dāng)需要在屏幕上進(jìn)行簡(jiǎn)單的繪制時(shí)-例如為顯示游戲初啟畫面,游戲結(jié)束屏幕以及游戲指令屏幕-這個(gè)canvas被擴(kuò)展,而取代了繁重的繪制。一個(gè)游戲程序的midlet可以包括任何個(gè)數(shù)的canvas,但是每次僅顯示一個(gè)canvas,這是通過(guò)使用javax.microedition.lcdui.Display類的setCurrent()方法來(lái)實(shí)現(xiàn)的。
HardDriveMIDlet還包含3個(gè)另外的重要方法,也稱作lifecycle方法。它們是startApp()、pauseApp()和destroyApp(),分別相應(yīng)于該midlet的Active,Paused和Destroyed狀態(tài)。在HardDriveMIDlet的startApp()方法中,實(shí)現(xiàn)實(shí)例化HardDriveCanvas并通過(guò)使用HardDriveCanvas類的方法addCommand()把EXIT命令添加到它上面去。
(二) HardDriveCanvas.java
HardDriveCanvas實(shí)現(xiàn)了一個(gè)java.lang.Runnable接口來(lái)使它自己可以運(yùn)行在自己的線程中,這對(duì)于獨(dú)立地執(zhí)行游戲循環(huán)是必需的。該游戲循環(huán)被連續(xù)不斷地執(zhí)行,直到終止游戲的必備條件滿足為止(在本例中,當(dāng)汽車碰撞到障礙物上或者在任何時(shí)候當(dāng)玩家使用Exit按鈕退出游戲)。
列表1.2:文件HardDriveCanvas.java中的游戲循環(huán)
- public void start()
- {
- gameRunning = true;
- Thread gameThread = new Thread(this);
- gameThread.start();
- }
- ... ... ... ...
- ... ... ... ...
- public void run()
- {
- Graphics g = getGraphics();
- //... ... ...一些代碼
- while (gameRunning) //游戲循環(huán)
- {
- tick();
- input();
- render(g);
- //... ... ...一些代碼
- try
- {
- Thread.sleep(timeStep );
- //... ... ... ...一些代碼
- }
- catch (InterruptedException ie) { stop(); }
- }
列表1.2顯示HardDriveCanvas.java中的游戲循環(huán)。這是一典型游戲循環(huán),它包含了依次對(duì)tick(),input()和render()方法的調(diào)用。tick()方法檢查是否停止該游戲的必需條件已經(jīng)滿足;如果滿足,即相應(yīng)地改變游戲的狀態(tài)。方法input()處理游戲的鍵盤(keys assigned for游戲playing)輸入并為每一次按鍵,如一個(gè)游戲元素的運(yùn)動(dòng),執(zhí)行必要的動(dòng)作。根據(jù)其所處的狀態(tài),著色任務(wù)由render()方法來(lái)完成。
HardDriveCanvas也使用一個(gè)javax.microedition.lcdui.game.LayerManager的實(shí)例來(lái)增加和管理多層的HardDriveCanvas,其中每一層代表一個(gè)精靈。一個(gè)精靈是一部游戲中一個(gè)基本的可視化元素,或者是一個(gè)在游戲畫布上移動(dòng)的character,而且它能夠與其它精靈(在這個(gè)示例中,汽車或障礙物都是精靈,它們可能進(jìn)行彼此碰撞。)進(jìn)行交互。每一個(gè)精靈形成一個(gè)虛擬層,它可能是全部或者部分透明地置于畫布之上;這些層彼此以堆棧方式堆疊。一個(gè)精靈是一個(gè)javax.microedition.lcdui.game.Sprite類的對(duì)象,它負(fù)責(zé)顯示、變形和旋轉(zhuǎn)精靈以及進(jìn)行精靈碰撞檢測(cè)。被內(nèi)部使用的tick()方法使用精靈類的collidesWith()方法進(jìn)行碰撞檢測(cè)。HardDriveCanvas實(shí)例化一個(gè)ObstacleManager類的對(duì)象,它用于著色并移動(dòng)游戲畫布上的障礙物精靈并檢查是否它們與汽車精靈相碰撞。
(三) ObstacleManager.java
ObstacleManager負(fù)責(zé)創(chuàng)建和管理隨機(jī)出現(xiàn)在汽車路徑上的障礙物。為了簡(jiǎn)化和便利,ObstacleManager.java硬編碼了每次出現(xiàn)在汽車路徑上的障礙物的最大數(shù)目值。這個(gè)值可以根據(jù)需要進(jìn)行修改。
列表1.3:該代碼片段來(lái)自于ObstacleManager.java
- private static final int MAX_OBS = 10;
- //... ...一些代碼
為了在隨機(jī)位置創(chuàng)建和顯示障礙物,ObstacleManager使用了一種簡(jiǎn)單的策略。它產(chǎn)生最初的10個(gè)障礙物精靈,并使用LayerManager來(lái)把這些精靈添加到游戲畫布上去。然后,它通過(guò)使用隨機(jī)產(chǎn)生的x和y坐標(biāo)值來(lái)設(shè)置它們的位置并開始朝著游戲畫布的底部移動(dòng)它們。一旦每一個(gè)障礙物到達(dá)了畫布的底部而沒有碰撞到汽車,它的位置就被通過(guò)使用相同的技術(shù)重新復(fù)位,而同時(shí)游戲的得分增加1。所以,ObstacleManager重用了同一個(gè)障礙物精靈并隨機(jī)地顯示它們。
(四) GameOverCanvas.java
GameOverCanvas是一個(gè)簡(jiǎn)單的canvas,它接收來(lái)自于HardDriveMIDlet游戲持續(xù)時(shí)間以及得分信息并顯示之。
#p#
五、 準(zhǔn)備示例游戲的發(fā)布
J2ME無(wú)線開發(fā)工具包提供了Ktoolbar-一個(gè)相當(dāng)有用的工具-可自動(dòng)化或半自動(dòng)化處理有關(guān)編譯,預(yù)先校驗(yàn),打包及測(cè)試移動(dòng)程序等一系列問(wèn)題。
既然現(xiàn)在準(zhǔn)備好了游戲代碼,那么就應(yīng)該把它們組織到由KToolbar提供的下面目錄結(jié)構(gòu)下(見Ktoolbar的用戶指南-"Operating with KToolbar")。為此,啟動(dòng)KToolbar并創(chuàng)建一新工程HardDriveGame,它將包含HardDrive游戲程序,該程序位于J2ME無(wú)線開發(fā)工具包的安裝文件夾下的apps子文件夾下。
HardDriveGame(定義用戶的游戲工程名)
| ___src
| ___bin
| ___classes
| ___res
| ___lib
| ___tmpclasses
| ___tmplib
現(xiàn)在,只要簡(jiǎn)單地復(fù)制游戲程序的四個(gè)源代碼文件到src文件夾下,把文件car.png和obstacle.png圖標(biāo)文件復(fù)制到res文件夾下。剩下的任何事情交由Ktoolbar處理好了。
接下去,下面操作將打開相應(yīng)的HardDriveGame游戲工程,編譯它(使用JDK編譯器),并預(yù)校驗(yàn)該游戲程序。
選擇"Open project"按鈕,選擇"HardDriveGame"->"Build"按鈕,即可開始工程構(gòu)建。
如果在工程創(chuàng)建過(guò)程中發(fā)生錯(cuò)誤,相應(yīng)信息會(huì)顯示在KToolbar窗口中。你可以修改src文件夾下的游戲源代碼來(lái)更改它們;但是,必須手工進(jìn)行調(diào)試,因?yàn)镵toolbar沒有提供調(diào)試工具。否則,如果沒有錯(cuò)誤發(fā)生,將顯示一條"構(gòu)建完成"信息于KToolbar窗口上。
一旦游戲工程創(chuàng)建成功,你就可以在仿真器(一個(gè)KToolbar組件,它虛擬地模擬移動(dòng)電話應(yīng)用程序的執(zhí)行)中運(yùn)行以進(jìn)行程序測(cè)試。
該游戲程序現(xiàn)在已開發(fā)完成,只等待發(fā)布了。為了使用KToolbar把游戲應(yīng)用程序打包成一個(gè).jar文件并進(jìn)行發(fā)布,應(yīng)執(zhí)行下面的步驟:選擇"Open project"按鈕,選擇"HardDriveGame"->"Project"菜單->"打包"->"Create package"/"Create obfuscated package"。
"Create package"菜單項(xiàng)將創(chuàng)建一標(biāo)準(zhǔn).jar文件,而"Create Obfuscated Package"將創(chuàng)建一個(gè)更小些的而不是一個(gè)標(biāo)準(zhǔn).jar文件。一旦打包完成,.jar文件的位置被顯示在KToolbar窗口中;在打包期間還自動(dòng)產(chǎn)生一個(gè).jad(Java應(yīng)用程序描述)文件,該文件在游戲程序運(yùn)行期間為仿真器所用。
圖1.1:運(yùn)行示例游戲應(yīng)用程序的模擬器
作為選擇,在打包后,你可以對(duì)游戲程序的midlet施加簽名,方法如下:
工程菜單->簽名;這將為.jar文件創(chuàng)建一個(gè)數(shù)字簽名并把它添加到.jad文件上。
現(xiàn)在,游戲應(yīng)用程序的.jar和.jad文件,還有用KToolbar創(chuàng)建的MANIFEST.MF manifest文件,組合在一起成為一個(gè)midlet 套件,都準(zhǔn)備好被發(fā)布了。
以上就是如何用Java進(jìn)行2D移動(dòng)游戲開發(fā)的整個(gè)過(guò)程。你可以根據(jù)本文提供的示例來(lái)構(gòu)建你自己的游戲。
六、 結(jié)論
隨著全世界移動(dòng)訂閱和移動(dòng)玩家數(shù)量的快速增長(zhǎng),移動(dòng)游戲開發(fā)正在成為一個(gè)賺錢的行業(yè)。J2ME和MIDP 2.0通過(guò)提供一種方便快捷高效的移動(dòng)游戲開發(fā)平臺(tái)幫助游戲開發(fā)者開拓這一領(lǐng)域所擁用的潛力。MIDP 2.0還提供了一套完整的API包,以用于游戲開發(fā),它提供了內(nèi)建的模塊來(lái)簡(jiǎn)化和加快移動(dòng)游戲開發(fā)。
【編輯推薦】