在 J2ME 開發中,不同手機廠商的按鍵碼差異極大,給跨平台遊戲開發帶來巨大挑戰。本文深入解析一個經典的 KeyCodeAdapter 類,展示如何將各平台原生按鍵碼統一映射為內部常量,實現「寫一次,到處運行」的按鍵處理邏輯。
KeyCodeAdapter 採用單例模式,在構造時自動檢測運行平台,並預先解析各功能鍵(左/右軟鍵、刪除鍵、返回鍵、中間/網絡鍵等)的真實按鍵碼。後續遊戲邏輯只需調用 adoptKeyCode() 即可將原生碼轉為統一常量。
類通過多重策略識別設備廠商:
microedition.platform 系統屬性識別 Nokia / Sony Ericssoncom.samsung.util.Vibration、com.motorola.multimedia.Vibrator 等)識別 Samsung、Motorola、Siemens、LGPLATFORM_NOT_DEFINED,並採用 Nokia/SE 默認碼以便模擬器運行內部定義統一常量(負數區間):
SOFT_KEY_LEFT = -201
SOFT_KEY_RIGHT = -202
SOFT_KEY_MIDDLE_INTERNET = -203
DELETE_KEY = -204
BACK_KEY = -205
PENCIL_KEY = -207 // Nokia S60 專用
UP_KEY = 221, DOWN_KEY = 222, LEFT_KEY = 223, RIGHT_KEY = 224, CENTER_KEY = 225
KEY_0..KEY_9, KEY_STAR, KEY_POUND = 200..212
對於 Motorola 等按鍵碼不固定的平台,構造器會遍歷候選碼,調用 Canvas.getKeyName() 獲取鍵名字符串,檢查是否包含 "SOFT" 及 "LEFT"/"RIGHT"/"1"/"2" 等關鍵字,動態確定真實碼值。
public int adoptKeyCode(int keycode) {
// 1. 數字鍵、*、# 直接映射
// 2. 功能鍵比對預解析的 SOFTKEY_LEFT/RIGHT/DELETE/BACK/MIDDLE
// 3. 方向鍵通過 Canvas.getGameAction() 映射 UP/DOWN/LEFT/RIGHT/FIRE
// 4. 未識別返回 NOT_DEFINED_KEY (254)
}
protected void keyPressed(int keyCode) {
int internalKeyCode = KeyCodeAdapter.getInstance().adoptKeyCode(keyCode);
switch (internalKeyCode) {
case KeyCodeAdapter.SOFT_KEY_LEFT: // 處理左軟鍵
break;
case KeyCodeAdapter.BACK_KEY: // 處理返回鍵
break;
// ...
}
}
該適配器封裝了繁瑣的平台差異處理,讓上層遊戲邏輯保持純淨。雖然現代 J2ME 開發已逐漸淡出,但其「平台適配層」的設計思想在跨平台框架開發中仍具參考價值。