開發程序:瘋狂的炸彈
開發進度:第二期
本期要點:設計客戶端網絡功能
開發平台:java平台
上期我們講了客戶端游戲功能,設計的程序只是一個單機游戲,為什麼會這樣呢?因為沒有網絡功能,無法進行通信。本期,我們就介紹客戶端網絡功能的設計。
客戶端網絡功能設計思路
客戶端網絡功能就是將客戶端的操作轉換為數據發送給服務器端,並將服務器端反饋的數據以界面的形式呈現給用戶。如果把所有的邏輯處理都放在服務器端,當然是最安全的形式,但是這樣服務器端的壓力會比較大,所以一般會將一些簡單的程序邏輯,例如本示例中移動時的邊界檢測,放在客戶端進行判斷。
設計客戶端網絡功能,要用到的指令有:准備(READY)、開始(START)、移動(MOVE)、取得游戲數據(GETDATA)和釋放炸彈(LAYBOMB)等幾種。在第一次連接時發送准備指令,從服務器端獲得一個唯一的用戶編號(userID),然後再發送開始指令給服務器,查看是否有其他用戶准備對戰。
如果沒有則循環發送開始指令,如果有用戶,則在服務器端分配房間號,然後服務器端新開設一個房間,並將游戲初始化數據反饋給客戶端,客戶端進入游戲界面。在游戲界面中,每隔1秒中向服務器端請求一次游戲數據,該請求中包含房間編號和用戶編號,當用戶移動時發送移動指令給服務器,當釋放炸彈時發送釋放炸彈指令給服務器(圖1)。
網絡協議設計
網絡協議(Protocol)是網絡程序的核心,也是一個網絡程序最核心的機密。網絡協議就是指網絡傳輸時的數據格式,由兩套格式組成:客戶端發送的數據格式和服務器端發送的數據格式。其中客戶端發送的數據格式和服務器端接收的數據格式相同,客戶端接收的數據格式和服務器端發送的數據格式相同。
在本程序中,客戶端需要發送的指令數量比較少,格式也不復雜,所以采用常見的“指令名稱+參數”的格式設計,即傳輸的數據中開始部分通過一個數據來代表指令的類型,而將該指令需要的參數以一定的格式跟隨在該指令的後面,形成一條完整的協議數據。跟詳細的介紹,請到http://www.shudoo.com/bzsoft下載。
監聽器模式分析
為了將客戶端界面和客戶端網絡編程有效的結合起來,並復用網絡編程部分的代碼,一種比較好的方法就是使用“監聽器模式”。監聽器模式是指在一個類執行功能到達某個步驟時,將處理該步驟的功能代碼委托給另外一個對象進行處理。
例如汽車上的警報器就采用了監聽器模式,汽車被移動時警報器對象就通過發出聲音進行處理。在網絡功能中,也采用監聽器模式,網絡通訊線程將服務器端數據的反饋委托給界面類中的方法進行處理,從而便於界面的控制,避免數據的大量傳輸。
在本示例中,聲明了一個HttpListener接口,實現該接口的類都具備處理網絡通訊反饋數據的能力,當網絡通訊中數據反饋以後,調用該接口中的doResponse方法進行處理。而每個需要進行網絡通訊的類都實現HttpListener接口,則每個界面類都具備了處理服務器端反饋數據的能力,然後在實現了的doResponse方法內部進行反饋數據的處理。
客戶端網絡功能設計步驟
第一步:創建項目
啟動Eclipse環境,選擇“File→New→J2ME MIDlet Suit”,設置項目名稱為“Bomber”,並一路選擇“Next”, 完成項目的建立。然後新建一個J2ME入口類,選擇“File→New→J2ME MIDlet”,設置名稱為“BomberMIDlet”,點擊“Finish”。最後,按照上期介紹的步驟編寫界面的代碼和按鍵處理的代碼(代碼下載地址:http://www.shudoo.com/bzsoft)
第二步:編寫網絡協議
選擇“File→New→Interface”,設置名稱為“RequestCommand”,點擊“Finish”完成客戶端發送指令接口的創建。輸入網絡協議代碼,其中關鍵代碼如下所示(完整代碼下載地址:http://www.shudoo.com/bzsoft):
public interface RequestCommand {
/**准備命令*/
public final static byte READY = 0x0;
/**開始命令*/
public final static byte START = 0x1;
/**移動命令*/
public final static byte MOVE = 0x2;
/**放炸彈命令*/
public final static byte LAYBOMB = 0x3;
/**退出命令*/
public final static byte QUIT = 0x4;
/**獲取游戲數據*/
public final static byte GETDATA = 0x5;
第三步:編寫網絡線程類
選擇“File→New→Class”,設置名稱為“HttpThread”,點擊“Finish”完成網絡線程類的創建。輸入網絡線程的代碼,其中關鍵碼如下所示(完整代碼下載地址:http://www.shudoo.com/bzsoft):
//建立連接
hc = (HttpConnection)Connector.open(SERVER);
//獲得輸出流
os = hc.openOutputStream();
//發送數據
os.write(data);
//讀取響應
if(hc.getResponseCode() == HttpConnection.HTTP_OK){
byte[] tmp = new byte[1024];
is = hc.openInputStream();
int n = is.read(tmp);
//生成有效數據
byte[] b = new byte[n];
System.arraycopy(tmp, 0, b, 0, n);
//處理反饋
listener.doResponse(b);
}else{
listener.doError("服務器反饋錯誤!");
第四步:在按鍵處理中添加發送指令
在已有的按鍵處理代碼基礎上,編寫發送指令的代碼。其中關鍵碼如下所示(完整代碼下載地址:http://www.shudoo.com/bzsoft):
playerDire = DIRE_UP; //改變方向
if(playerY - BOX_TILE_HEIGHT > 22){//邊界檢測
new HttpThread(generateMoveData(DIRE_UP),this); //發送指令
}
break;
case DOWN:
playerDire = DIRE_DOWN; //改變方向
if(playerY + SPRITE_HEIGHT + BOX_TILE_HEIGHT < 210){//邊界檢測
new HttpThread(generateMoveData(DIRE_DOWN),this); //發送指令
}
break;
case LEFT:
playerDire = DIRE_LEFT; //改變方向
if(playerX - TILE_WIDTH > 0){//邊界檢測
new HttpThread(generateMoveData(DIRE_LEFT),this); //發送指令
}
break;
case RIGHT:
playerDire = DIRE_RIGHT; //改變方向
if(playerX + TILE_WIDTH + SPRITE_WIDTH < width){//邊界檢測
new HttpThread(generateMoveData(DIRE_RIGHT),this); //發送指令
第五步:運行程序
在Eclipse主界面左側的“Package Explorer”中,選中項目源代碼BomberMIDlet.java,單擊鼠標右鍵,選擇“Run As→Emulated J2ME Midlet”即可運行程序。
讀者反饋
開發qq群:看了上期的文章,《瘋狂的炸彈》游戲界面可以改變成3D嗎?
小編:可以修改成3D效果的界面,從而獲得更加良好的界面體驗。修改時主要影響程序中的界面繪制部分,對於用戶操作控制以及網絡部分都幾乎不影響,程序的修改不會很麻煩。
開發QQ群:S60模擬器啟動時閃一下就關閉了,為什麼會這樣?我在網上找了很久,都沒有找到,所以才加入你們的群,請幫幫我!
小編:出現這種情況的原因有很多,下面列舉幾種比較常見的原因:1.編寫的程序在運行是遇到錯誤或異常,閱讀代碼找出錯誤原因再進行修改 。2.模擬器的安裝出現錯誤,重新安裝模擬器。3.程序配置錯誤,重新配置開發環境。
開發QQ群:我的程序出現提示:Undefined symbol: 'int RSendAs::Connect(void) (?Connect@RSendAs@@QAEHXZ)',頭文件加了的,為什麼還會這樣?
小編:為什麼會這樣,憑我的經驗來看,應該是沒有添加類庫的引用,你添加過來再看看,應該就不會出現這樣的提升了。
開發QQ群:我正在做一個軟件,其中有一項是日期選擇,我想調用一個現成的控件來實現,應該怎麼做?希望高手給一點建議。
小編:這個需要看你開發時使用的語言和技術。如果你在開發時使用的是Java ME技術,而且使用高級用戶界面進行開發,則可以使用DateField控件,如果使用低級用戶界面進行開發,那麼就需要自己實現界面的繪制和邏輯處理。
讀者問題:手機開發中有支持移動定位技術的嗎?
高手 悠然鳥:有的,例如在Java ME技術中,有一個可選包JSR179 Location API專門支持移動定位技術開發,如果手機支持該可選包,則開發者再進行開發時則可以直接使用該API提供的功能。
讀者問題:在手機來電時立即暫停程序,這個功能是怎麼實現的?
你是手機編程的高手嗎?你能解答上面這位讀者的疑問嗎?不要猶豫,來我們這裡展示一下你的風采吧,來信請發到[email protected](也可以給我們發送問題)。