在早期的 J2ME 遊戲開發中,按鍵處理一直是開發者頭疼的問題。MIDP 1.0 時代,開發者只能依賴 keyPressed、keyReleased、keyRepeated 這三個回調函數來處理玩家輸入。雖然這種方式概念簡單,但在實際遊戲開發中卻暴露出兩個致命缺陷:
paint() 重繪,導致畫面卡頓、幀率下降。MIDP 2.0 引入了 GameCanvas 類,徹底改變了按鍵處理模式——採用「按鍵狀態字」機制,完美解決了上述問題。
// 建構子參數 suppressKeyEvents 為 true 時抑制傳統按鍵事件回調,減少系統開銷
GameCanvas canvas = new GameCanvas(true);
// 在遊戲主迴圈每幀開頭獲取當前按鍵狀態
int keyState = getKeyStates();
getKeyStates() 返回一個 int 值,每一個位元對應一個按鍵是否被按下(1 為按下,0 為釋放)。這種位元級操作不僅天然支援多鍵同按,還將按鍵檢測從事件回調移至主迴圈主動輪該,避免了執行緒爭用,效能顯著提升。
// 判斷左/右鍵是否按下
if ((keyState & LEFT_KEY) != 0) { /* 處理左移 */ }
else if ((keyState & RIGHT_KEY) != 0) { /* 處理右移 */ }
記錄上一幀按鍵狀態 lastKeyState,配合當前狀態 curKeyState,可通過位元運算精確捕捉按鍵事件:
int newKeys = ~lastKeyState & curKeyState; // 新按下的鍵(相當於 keyPressed)
int lostKeys = lastKeyState & ~curKeyState; // 釋放的鍵(相當於 keyReleased)
int changedKeys = lastKeyState ^ curKeyState; // 狀態發生變化的鍵
若當前 GameCanvas 非正在顯示的 Displayable,getKeyStates() 恆返回 0。
若在按住按鍵時切換回該 Canvas,getKeyStates() 仍返回 0,必須等按鍵釋放再重按才能正常檢測。
在部分機型(如 VT603)上,長按軟鍵會觸發系統自動重複回調 commandAction,導致遊戲暫停/繼續狀態閃爍。臨時方案:
keyPressedEx/keyReleasedEx 自定義方法CommandListenergetKeyStates(),手動觸發邏輯最佳實踐:新專案請優先採用 getKeyStates() 主動輪詢模式,棄用傳統事件回調。
Canvas.getKeypadState()DeviceControl 實例:DeviceControl.getDefaultDeviceControl()dc.getDeviceState(DeviceControl.KEY_STATE)其他按鍵位元映射請參閱各平台 Display 或 DeviceControl 類文檔。