我寫第一個J2ME游戲的時候,基本就沒想過移植的標題。所以那個游戲也就很難移植了。反過來,假如你已經打算好要移植了,那麼事情就簡略的多。這一節說的是代碼標題。那就想想,不同手機之間在代碼上會有哪些差別。
(1) 屏幕尺寸不同
這兒談的重要標題,是自適應控件。所謂控件,就是菜單、文本框、列表框、進度條等等。這些控件的大小必需可以根據屏幕大小自適應的調劑。按照第一篇說的方法,將屏幕大小作為變量參與到控件尺寸的盤算即可得到准確的尺寸(自適應後的)。其次就是得到准確尺寸後怎麼把它畫出來。
這要看你的GUI是怎麼畫得了,假如是用線畫的,那就很簡略;假如應用了圖片,那麼就可能要調換圖片了。我的控件應用了圖片平展和畫線聯合,所以可以很輕易的轉變尺寸。假如控件變大了,則繪制時增加平展的次數即可。
順便說一下,這些控件我只用了一個類表現,應用參數化的方法區分應用,畢竟咱要盡量少用類吧。
(2) 支撐的API不同
假如你的游戲只限於應用Midp1.0,那麼移植的時候就不用考慮什麼了。實際上由於我們經常要應用圖片翻轉、象素繪制、全屏等,往往要用到廠商API或Midp2.0。顯然移植的時候要考慮到這些API的差別。
我的措施是將這些api封裝一層,比如我需要應用創立透明子圖的API,於是封裝了一個函數createSubImg。這是諾基亞版本:
public static Image createSubImg(Image img,int []imgRect)
{
Image subImg = DirectUtils.createImage(imgRect[2],imgRect[3],0) ;
subImg.getGraphics().drawImage(img,-imgRect[0],-imgRect[1],20);
return subImg ;
}
這是Midp2.0版本:
public static Image createSubImg(Image img,int []imgRect)
{
return Image.createImage(img,imgRect[0],imgRect[1],imgRect[2],imgRect[3],0) ;
}
對於不同機型,該函數的實現不同,但功效雷同,因此應用這個函數的代碼在移植時無需修正。當然這樣做增加了一些間接性,有可能下降性能。
(3) 按鍵代碼不同
我們知道MIDP供給了Game Action,和按鍵代碼無關,但這不夠用啊,我們完整可以定義自己的Game Action,但首先讓我們定義自己的虛擬按鍵碼吧。我應用位記錄每個鍵的狀態,每個位代表一個按鍵,一個int有32個位所以足夠了。
當keyPressed產生時,我記下哪些鍵被按下;同樣當keyReleased時,將那些被松開的鍵應用的位清0。某個鍵,也就是這個鍵盤狀態整數裡的某個位,就是我定義的一個虛擬鍵。當然它的值總是2的n次方了,和key code完整不搭邊,所以需要我們用一個映射函數將keycode映射到這些虛擬鍵。
這個函數就是移植的要害,每個機型都要改寫這個映射函數,在裡面填進准確的key code。你可以在虛擬鍵的基礎上再定義Game Action,支撐在游戲中設置按鍵,這樣就更機動了。
(4) 封裝庫
假如想不更改一行代碼就從MotorolaV600移植到諾基亞N-Gage,那麼為他們封裝不同的庫吧。我就這樣在1分鐘內完成了移植。我的庫包含了一個游戲框架類(內含游戲循環和渲染函數,鍵盤處理,以及若干跨機型的工具函數),一個圖形組治理類(治理圖片的載進切割旋轉繪制和動畫等,有點像GameAPI中的Sprite)和一個控件類(包含了所有我需要的控件)。
這3個類封裝了不同機型的所有差別,我需要為每種機型改寫這三個類,當然大部分代碼是雷同的了。此外我還寫了一個工具支撐圖形組治理類,所見即所得的編纂動畫和治理圖片,當然這也對移植有幫助。
總結:
以上幾條,總得講來,無非是拆合而以。重要是要將差別性獨立出來,便於更改。但是移植總得來講還是比擬愁悶,重要原因是各種機型有各自的bug,這就需要特別處理啦。各位寫代碼時必定要想好移植的標題啊!