不同手機螢幕尺寸各異,渲染時必須以變數 ScreenWidth、ScreenHeight 參與座標計算。例:置中繪製 Logo——x = (ScreenWidth - ImageWidth) / 2。RPG 地圖繪製亦同理:TilesX = ScreenWidth / TileWidth,而非寫死 8×8 迴圈。
利用 Font.getHeight() 取得字體高度,Font.stringWidth(str) 計算字串寬度(支援非等寬字體與中英混排)。應用例:軟鍵選單繪製——左鍵 (0, canvasHeight - fontHeight),右鍵 (canvasWidth - stringWidth(rightKey), canvasHeight - fontHeight)。
定義虛擬螢幕區域 vsX, vsY, vsWidth, vsHeight,邏輯座標系統在虛擬螢幕內運算,渲染時映射至真實螢幕:real_x = x + vsX。優點:
① 大螢幕模擬器開發時保留區域顯示除錯資訊;
② 支援多分屏遊戲;
③ 可定義超大虛擬世界(如 1024×1024),渲染時按比例縮放映射。
小結:將所有可能變化的數值定義為變數或常數,使用相對座標,可大幅提升可移植性。混淆器會內聯 final static,無效能損失。
控件尺寸隨螢幕自適應調整。若用圖片繪製,採用平鋪+畫線組合,調整尺寸只需改變平鋪次數。所有控件集中在單一類別,參數化區分用途。
常需廠商 API 或 MIDP 2.0(圖片翻轉、像素操作、全螢幕)。封裝統一介面,不同平台提供不同實現:
// Nokia 版
public static Image createSubImg(Image img, int[] rect) {
Image sub = DirectUtils.createImage(rect[2], rect[3], 0);
sub.getGraphics().drawImage(img, -rect[0], -rect[1], 20);
return sub;
}
// MIDP 2.0 版
public static Image createSubImg(Image img, int[] rect) {
return Image.createImage(img, rect[0], rect[1], rect[2], rect[3], 0);
}
調用端無需修改,雖增加間接呼叫但功能一致。
MIDP 提供 GameAction 但不足夠。自訂虛擬按鍵碼(位元遮罩,一個 int 32 位足夠),keyPressed/keyReleased 記錄狀態,提供 getKeyValue(keyCode) 映射函數將實體鍵碼轉為虛擬鍵。移植時僅需改寫此映射函數。可在此基礎上定義自訂 GameAction,支援遊戲內按鍵設定。
核心三類別封裝所有平台差異:
① 遊戲框架類(主迴圈、渲染、鍵盤處理、工具函數)
② 圖形組管理類(圖片載入/切割/旋轉/繪製/動畫,類 Sprite)
③ 控件類(所有 UI 控件)
移植時僅重寫這三個類別,大部分程式碼復用。輔以自製動畫編輯工具支援圖形組管理。
總結:核心在於「拆合」——將差異性獨立封裝,便於更換。但各機型特有 Bug 仍需特殊處理,移植依然較繁瑣。寫程式時請為移植著想!