J2ME 遊戲開發中,按鍵響應是核心邏輯。手機鍵盤分為功能鍵區(軟鍵、導航鍵、通話鍵)與數字鍵區(0-9、*、#)。功能鍵的鍵值跨機型差異極大,數字鍵則相對統一。
protected void keyPressed(int keyCode) {
// 方式 A:直接比對 keyCode(不推薦,可讀性差)
if (keyCode == 52) { ... }
// 方式 B:使用 Canvas 常數(推薦)
if (keyCode == Canvas.KEY_NUM4) { ... }
}
缺點:所有邏輯(延遲、輸入響應、重繪)耦合在系統事件執行緒,長時間運算會阻塞 UI,導致按鍵響應延遲甚至丟失。
將物理鍵映射為統一的遊戲動作常數:
| 遊戲動作 | 對應鍵位 |
|---|---|
| Canvas.UP | 數字鍵 2、向上導航鍵 |
| Canvas.DOWN | 數字鍵 8、向下導航鍵 |
| Canvas.LEFT | 數字鍵 4、向左導航鍵 |
| Canvas.RIGHT | 數字鍵 6、向右導航鍵 |
| Canvas.FIRE | 數字鍵 5、確定鍵 |
| GAME_A/B/C/D | 1/3/7/9 或 7/9/*/# |
int action = getGameAction(keyCode);
switch (action) {
case Canvas.LEFT: // 向左移動
break;
case Canvas.FIRE: // 射擊/確認
break;
}
解決了跨機型按鍵差異,但仍受限於 keyPressed 回調模型。
原理:系統維護一個位元組,每個位對應一個遊戲動作鍵的按下狀態(1=按下,0=釋放)。
public class MyGameCanvas extends GameCanvas {
public MyGameCanvas() {
super(true); // true 表示啟用按鍵狀態機制
}
}
public void run() {
while (running) {
int states = getKeyStates(); // 獲取並清空狀態
if ((states & LEFT_PRESSED) != 0) { /* 向左 */ }
if ((states & RIGHT_PRESSED) != 0) { /* 向右 */ }
if ((states & FIRE_PRESSED) != 0) { /* 射擊 */ }
// 遊戲邏輯更新
// 重繪畫面
flushGraphics();
Thread.sleep(50);
}
}
優勢:
限制:僅限 GameCanvas 子類,僅處理遊戲相關鍵;啟用後 keyPressed 不再接收遊戲鍵事件。
| 場景 | 推薦技術 |
|---|---|
| 簡單表單/選單導航、非遊戲應用 | keyPressed + Canvas 常數 |
| MIDP 1.0 遊戲、需跨機型相容 | gameAction 映射 |
| MIDP 2.0 即時遊戲、動作/射擊類、需多鍵併發 | keyStates (GameCanvas) |