【文章內(nèi)容簡(jiǎn)介】
們顯示的順序。 3. Canvas 類 Canvas 類是低級(jí)別 MIDP UI 的基礎(chǔ)。它提供對(duì)在整個(gè)屏幕之上的像素級(jí)繪畫(huà)的訪問(wèn)以及對(duì)用于所有硬件鍵的自定義映射的訪問(wèn) [1 ]。你 可以只創(chuàng)建 Canvas 的子類并且跳過(guò)用于顯示邏輯的 paint()函數(shù),用于鍵事件的 keyPressed(), keyRepeated(),和 keyReleased()函數(shù) ,以及用于每個(gè)事件中指示器和觸摸屏的 pointerP ressed(), pointerDragged()和 pointerReleased()函數(shù) [1 8 ]。 4. MIDlet 類 調(diào)用 new()建 MIDlet 類,如圖 32 所示 。 startGame() MIDlet 類程序啟動(dòng)時(shí)運(yùn)行的代碼 pauseApp() MIDlet 類程 序暫停時(shí)運(yùn)行的代碼 destroyApp() MIDlet 類程序終止時(shí)運(yùn)行的代碼 在實(shí)現(xiàn)整個(gè)程序的運(yùn)行,必須調(diào)用上述 MIDlet 類里面的函數(shù),它們構(gòu) 成 了 一 個(gè) 完 整 的 程 序 實(shí) 現(xiàn) 過(guò) 程 。 一 個(gè) MIDP 應(yīng)用程序稱做MIDletMIDP 小應(yīng)用程序,它不能單獨(dú)運(yùn)行,都必須運(yùn)行在特定的運(yùn)行環(huán)境之中,或說(shuō)運(yùn)行在一個(gè)容器中 [1 8 ]。 P a u s e d A p p ( )S t a r t A p p ( )D e s t r o y e d A p p ( )D e s t r o y e d A p p ( )啟 動(dòng) 狀 態(tài)A c t i v e暫 停 狀 態(tài)P a u s e d摧 毀 狀 態(tài)D e s t r o y e d 圖 32 MIDlet 狀態(tài)轉(zhuǎn)換 可以把這個(gè)容器看作是個(gè)大的應(yīng)用程序,它運(yùn)行在 Java 虛擬機(jī)之上, 但不能完成任何特定的任務(wù),因此需要程序開(kāi)發(fā)者編寫(xiě)代碼以完成一項(xiàng)工作,這些編寫(xiě)的程 序就稱小應(yīng)用程序 [1 ]。這樣設(shè)計(jì)的目的是為了讓它能在所有的容器中運(yùn)行,這些容器實(shí)現(xiàn)可能不同,但它能運(yùn)行在多種環(huán)境中。 MIDlet 中這個(gè)容器就是 MIDP 實(shí)現(xiàn),它以 S un 公司發(fā)布的 C LDC 規(guī)范和 MIDP 規(guī)范為標(biāo)準(zhǔn),然后針對(duì)設(shè)備進(jìn)行移植,從而提供給所有 MIDlet 都一樣的容器內(nèi)部接口。 MIDP 實(shí)現(xiàn)提供有一套機(jī)制用來(lái)管理 MIDlet,比如運(yùn)行、暫停、銷毀等。因此對(duì) MIDP小應(yīng)用程序來(lái)說(shuō),也應(yīng)該遵照一個(gè)標(biāo)準(zhǔn),比如必須實(shí)現(xiàn)一定的接口應(yīng)用管理軟件才可識(shí)別并調(diào)用它。編寫(xiě) MIDP 應(yīng)用程序要求就是必須擴(kuò)展 MIDlet 類,這個(gè)類 定義了一些接口,應(yīng)用管理軟件可以通過(guò)這些接口對(duì) MIDlet 進(jìn)行控制 [5 ]。 MIDlet 類 位 于 以 下 包 中 : 。 import .*midlet 包對(duì) MIDP 應(yīng)用程序進(jìn)行了定義,也定義了應(yīng)用程序和它所運(yùn)行的環(huán)境之間的接口,如前面所述 MIDP應(yīng)用程序被稱作 MIDlet。 MIDlet 有以下?tīng)顟B(tài) [2 ]: Paused: MIDlet 已經(jīng)被初始化并且處于靜止,它不擁有或使用任何享資源。 Active: MIDlet 正常運(yùn)行狀態(tài),調(diào) 用函數(shù) ()之前會(huì)進(jìn)入這個(gè)狀態(tài)。 Destroyed: MIDlet 釋放掉所有它的資源并終止運(yùn)行。 5. Bluetooth 可選包 Bluetooth 是 J2ME 為手機(jī)游戲開(kāi)發(fā)提供的一個(gè)可選包。它的主要功能是為 需要 使用 藍(lán)牙 設(shè)備 進(jìn)行 信息 通信 的手 機(jī)游 戲提 供可 用的 方法。在 Bluetooth 中提供了許多有用的類,例如 DiscoveryListener、ServiceRecord 、 DeviceC lass 、 DiscoveryAgent 、 LocalDevice 、RemoteDevice、 UUID 等。這 些類為開(kāi)發(fā)者提供了藍(lán)牙設(shè)備的尋找遠(yuǎn)端設(shè)備、建立連接、發(fā)現(xiàn)服務(wù)、發(fā)送數(shù)據(jù)、接收數(shù)據(jù)等功能,使得手機(jī)游戲支持藍(lán)牙設(shè)備的使用 [1 9 ]。 第 4 章 聯(lián)網(wǎng)五子棋游戲的實(shí)現(xiàn) 游戲圖形界面的設(shè)計(jì) 首先在手機(jī)屏幕上要畫(huà)一個(gè)棋盤(pán)及背景畫(huà)面。先在系統(tǒng)中添加了一張 *.png 的圖片,如圖 41 所示。這個(gè)就好像一個(gè)拼圖的游戲。 圖 41 五子棋棋盤(pán)的基本構(gòu)成 在下棋的時(shí)候無(wú)論界面如何變化,棋盤(pán)的圖形總是有十二個(gè)不同的圖片組成,因此選用了圖 41 這張具有上述信息的 PNG 圖。先畫(huà)上下左右四個(gè)棋盤(pán)的邊緣,們有四個(gè)不同的圖 象組成,然后是四個(gè)角。有了這個(gè)框架后,繼續(xù)往棋盤(pán)里面填充,里面圖形基本相同 (除了四個(gè)特殊的點(diǎn)以外 ),這樣棋盤(pán)界面的繪制就完成了。同樣的,也采用這個(gè)辦法截取黑棋子和白棋子。在手機(jī)用戶游戲時(shí)進(jìn)行調(diào)用和顯示。 五子棋游戲界面接口設(shè)計(jì) 本系統(tǒng)中,五子棋游戲的界面接口設(shè)計(jì)主要分為兩大部分:游戲中登錄界面的接口設(shè)計(jì)和游戲控件,手機(jī)鍵盤(pán)按鍵功能的設(shè)計(jì)。 游戲中登錄界面的接口設(shè)計(jì) 在登錄界面 BTGame 類中使用到了 C hoiceGroup、 Form、 Command,來(lái)實(shí)現(xiàn)登錄界面中登錄信息框的信息和功能按 鈕的控制。 在本系統(tǒng)中 Command 類被用來(lái)控制兩個(gè)功能按鈕 , 登錄按鈕 (P lay)和退出按鈕 (Exit )。它們的具體實(shí)現(xiàn)方式如 圖 42 所示 。 e x i t C o m m a n d = n e w C o m m a n d ( E x i t , C o m m a n d . e x i t , 0 ) 。 p l a y C o m m a n d = n e w C o m m a n d ( L o g i n , C o m m a n d . p l a y , 0 ) 。 圖 42 ChoiceGroup 類被用來(lái)控制兩個(gè)選項(xiàng) , 服務(wù)器 (S ERVER)選項(xiàng)和客戶端 (CLIENT )。它們的具體實(shí)現(xiàn)如 圖 43。 S t r i n g [ ] p e e r N a m e s = { ― S e rv e r‖ , ‖ C lie n t‖ } 。C h o i c e s = n e w C h o i c e G r o u p ( ― P le a s e s e le c t p e e r ty p e : ‖ , C h o i c e . E X C L U S I V E , p e e r N a m e s , n u l l 。 ) 圖 43 游 戲控件,手機(jī)鍵盤(pán)按鍵功能的設(shè)計(jì) 在控件的實(shí)現(xiàn)過(guò)程中用到了 GameCanvas 類。 GameCanvas 類繼承于 Canvas 類 , 它是 MIDP v2 游戲 AP I 的一部分并且為游戲開(kāi)發(fā)提供了便利機(jī)制。例如 :在 GameCanvas 子類中,每次修改時(shí)不需要跳過(guò) paint()函數(shù)就可以描繪整個(gè)屏幕,直接從 getGraphics()函數(shù)中得到Graphics 對(duì)象并且在該對(duì)象上繪圖。當(dāng)需要更新顯示時(shí),可以調(diào)用flushGraphics()函數(shù),但當(dāng)使用 flushGraphics()函數(shù)時(shí)就只需要更新屏幕的一部分。相比 Canvas 類的單一方法而言, GameCanvas 類更加易于 保持 圖形 狀態(tài) ,易 于迅 速更 新屏 幕的 動(dòng)畫(huà) 部分 。類 似的 ,GameCanvas 類使用和 C anvas 類中回叫方法相反的 getKeyS tates()函數(shù),為獲得鍵狀態(tài)提供了一個(gè)便利的途徑。這使得復(fù)雜游戲屏幕類中的執(zhí)行流動(dòng)性要靈活的多。 GameCanvas 和 Canvas 的按鍵狀態(tài)的響應(yīng)是不一樣的 [3 ]。在調(diào)用 C anvas 類時(shí),如果想知道按鍵狀態(tài),就必須實(shí)現(xiàn) keyPressed(int keyCode),每當(dāng)有鍵被按下時(shí),這個(gè)函數(shù)就被調(diào)用。而使用 GameC anvas 時(shí),要想知道某個(gè)鍵是否被調(diào)用的時(shí)候 ,直接調(diào)用 getKeyS tates()函數(shù)就可以了。當(dāng)然 getKeyS tates()的返回值會(huì)在另外一個(gè)線程中被更新,所以在游戲主循環(huán)中最好稍微登上一會(huì),以保證這個(gè)值被更新。游戲動(dòng)作是虛擬的按鍵,它與物理按鍵 之間的映射有 MIDP 實(shí)現(xiàn)完成,使用函數(shù) getKeyS tates()中的把游戲動(dòng)作翻譯成相應(yīng)的按鍵代碼。 在本系統(tǒng)中,對(duì)手機(jī)數(shù)字鍵做了功能上的定義: 5 分別實(shí) 現(xiàn) 以 下功 能 Down Pressed( 向下 ) 、 Left Pressed( 向左 ) 、 Right Pressed(向右 )、 Up Pressed(向上 )、 F irees Pressed(確定 )。 五子棋游戲過(guò)程的設(shè)計(jì) 對(duì)于五子棋游戲,其游戲過(guò)程主要包括了游戲登錄、下棋過(guò)程、勝負(fù)判定和游戲結(jié)束四個(gè)過(guò)程。游戲的設(shè)計(jì)流程如圖 44 所示。 游戲登錄:包括了兩個(gè)手機(jī)玩家選擇服務(wù)器和客戶機(jī),完成兩個(gè)五子棋游戲玩家的對(duì)接兩個(gè)過(guò)程。 下棋過(guò)程:體現(xiàn)了兩個(gè)玩家通過(guò)藍(lán)牙設(shè)備實(shí)現(xiàn)游戲交互的過(guò)程。 勝負(fù)判定:獲取棋子信息,即通過(guò)對(duì)棋盤(pán)上棋子的位置,采用設(shè)計(jì)的算法,來(lái)判斷哪一方先達(dá)到相連的棋子達(dá)到 5 個(gè)。 游戲結(jié)束:在游戲結(jié)束時(shí),通過(guò) 藍(lán)牙設(shè)備傳輸勝負(fù)信息,顯示勝負(fù)的信息給兩個(gè)玩家。最后,玩家退出游戲。 游戲登錄過(guò)程手機(jī)玩家( 1 )手機(jī)玩家( 2 )游戲登錄過(guò)程游戲過(guò)程 游戲過(guò)程勝負(fù)判斷游戲結(jié)束勝負(fù)判斷游戲結(jié)束藍(lán)牙設(shè)備 圖 44 五子棋的游戲過(guò)程流程圖 五子棋游戲的流程設(shè)計(jì) 本系統(tǒng)調(diào)用 J2ME 自帶的 MIDlet 類,程序從 startApp()函數(shù)入口開(kāi)始運(yùn)行,另外還包含以下的函數(shù): initialization()初始化棋盤(pán)數(shù)據(jù) draw 把棋子下到棋盤(pán)上 hwin()檢測(cè)水平是否有五個(gè)棋子 vwin()檢測(cè)垂直是否有五個(gè)棋子 b1win()檢測(cè)對(duì)角線 1 是否有五個(gè)棋子 b2–win()檢測(cè)對(duì)角線 2 是否有五個(gè)棋子 程序通過(guò) startApp()函數(shù)調(diào)入了手機(jī)登錄界面,當(dāng)用戶點(diǎn)擊登錄界面里的 play 按鈕,進(jìn)入 startGame()函數(shù)準(zhǔn)備開(kāi)始游戲。用戶開(kāi)始游戲的處理使用 startGame()函數(shù),在開(kāi)始游戲前需要先對(duì)連接建立進(jìn)行判斷,如果連接成功則可以開(kāi)始游戲。如果第一個(gè)用戶得到允許開(kāi)始下棋的標(biāo)志,則第一個(gè)用戶被賦給紅棋并可以開(kāi)始下棋,如果不可以則判斷第二個(gè)用戶是否可以,如果可以則第二個(gè)用戶被賦給白棋,并可以開(kāi)始下棋,兩個(gè)用戶用 true,truel 來(lái)加以區(qū)別。然后建立新的 GUI 類 , 并 初 始 化 棋 盤(pán) , 雙 方 開(kāi) 始 游 戲 。 程 序 通 過(guò)ReceiveC hessThread 的 getC hessX(), getC hessY()函數(shù)來(lái)獲取棋子信息,并在客戶界面上顯示棋子的位置,直到有一方已經(jīng)贏得了游戲,停止循環(huán)。然后發(fā)送贏家的 ID 給服務(wù)器,顯示勝利界面。 PauseApp()函數(shù)的功能是暫停游戲。 DestroyApp()和 exit()函數(shù)都是用來(lái)處理關(guān)閉程序。 Initialization()函數(shù)用來(lái)初始化整個(gè)棋盤(pán)。 在開(kāi)始下棋前,界面上只有一個(gè)小方格。界面中的每個(gè)位置都用二維數(shù)組 chessdate[][]來(lái)表示,結(jié)合 drawO ffScreenGraphics 的方法,把chessdate[][]全部設(shè)置為 2,用一個(gè)條件語(yǔ)句來(lái)判定該位置的棋子是空的。當(dāng)白棋或者紅棋走一步后,將 chessdate[][]設(shè)置為 0 或 1 下棋的過(guò)程中其實(shí)就是棋子位置的數(shù)據(jù)不斷在客戶端 ——藍(lán)牙設(shè)備 ——客戶端之間傳遞的過(guò)程 [2 1 ]。 具體的游戲?qū)崿F(xiàn)流程如圖 45 所示。 1.玩家 1 下棋 玩家 1 在得到確認(rèn)允許下棋后,調(diào)用函數(shù) setC hess(int x,int y,int ChessType)來(lái)放置棋子。其中 x,y 分別代表棋盤(pán)的橫坐標(biāo)和縱坐標(biāo),ChessType 代表棋的顏色 (在登錄時(shí)己經(jīng)設(shè)置完成了 )。用一個(gè)二維數(shù) 組 chess[x][y]來(lái)記錄棋盤(pán)的下棋信息 (0,表示未下; 1,表示己下的為紅棋; 2,代表己下的為白棋 )。同時(shí)將剛剛放置棋子的坐標(biāo)代入到chess[x] [y]中,判斷 chess[x][y]的值是否為 0,用來(lái)判斷能否在該位置下棋 (保證了棋盤(pán)的每一個(gè)位置只能放一個(gè)棋 )。放置后,將當(dāng)前下棋的坐標(biāo)信息保存到另一個(gè)二維數(shù)組 chessdate[x][y]中,將這些信息通過(guò)藍(lán)牙設(shè)備發(fā)送給玩家 2。同時(shí),玩家 1 進(jìn)入等待再被允許下棋狀態(tài)。 對(duì)弈開(kāi)始允許下棋玩家 ( 1 ) 下棋是否獲勝允許下棋玩家 ( 2 ) 下棋是否獲勝判斷勝負(fù)游戲結(jié)束等待NOY E SNONOY E SNOY E SY E S 圖 45 五子棋算法 2.玩家 2 下棋 玩家 2 過(guò)藍(lán)牙設(shè)備接收到玩家 1 剛才的下棋信息 后,用以上同樣的方法來(lái)放置棋子,用接收信息中的坐標(biāo)值 x,y 代入到 chess[x][y],判斷 chess[x][y]能否在該位置下棋,并將當(dāng)前的下棋信息 chessdate[] [],發(fā)送給玩家 1。 3.判定勝利 通過(guò) ReceiveC