首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> Java 程式設計 >> Java 程式設計入門

J2ME 低級界面三大事件處理機制對比:keyPressed、gameAction 與 keyStates 深度解析

     編輯:Java 程式設計入門

前言:按鍵處理是遊戲交互的心跳

J2ME 低級界面 (Canvas/GameCanvas) 事件處理經歷三代演進:keyPressed 覆蓋 → gameAction 映射 → keyStates 位掩碼。本文深度對比三者機制、適用場景與代碼模式。

一、第一代:覆蓋 keyPressed(int keyCode) (MIDP 1.0)

1. 機制

protected void keyPressed(int keyCode) {
    // 系統自動調用,傳入原始鍵碼
}

2. 兩種鍵碼判斷方式

3. gameAction 映射表 (設備廠商實現)

方式代碼示例優缺點
直接比較 keyCodeif (keyCode == 52) ... 或 if (keyCode == Canvas.KEY_NUM4) ...✅ 可讀性差(魔術數字) / ✅ 推薦用常量
gameAction 映射int action = getGameAction(keyCode);
switch(action) { case Canvas.LEFT: ... }
✅ 屏蔽設備差異 / ✅ 遊戲邏輯統一
Game Action典型物理鍵
Canvas.UP數字鍵 2、向上導航鍵
Canvas.DOWN數字鍵 8、向下導航鍵
Canvas.LEFT數字鍵 4、向左導航鍵
Canvas.RIGHT數字鍵 6、向右導航鍵
Canvas.FIRE數字鍵 5、確定/中間鍵
Canvas.GAME_A/B/C/D1/3/7/9 或 7/9/*/# (設備差異大)

4. 核心缺陷:三大邏輯強耦合

// 在系統事件線程 (EDT) 中執行
protected void keyPressed(int keyCode) {
    // 1. 響應用戶操作
    // 2. 更新遊戲狀態 (邏輯)
    // 3. 觸發重繪 repaint()
}
// 導致:邏輯執行時間長 → 界面卡頓、按鍵丟失、重繪不及時

二、第二代:keyStates 位掩碼機制 (MIDP 2.0 GameCanvas)

1. 核心原理

  • 系統維護一個 int 位掩碼,每位對應一個遊戲動作 (UP/DOWN/LEFT/RIGHT/FIRE/GAME_A-D)
  • 按鍵按下 → 對應位置 1;釋放 → 置 0
  • 開發者在**遊戲主線程**中主動輪詢:int states = getKeyStates();
  • 關鍵優勢:讀取瞬間**自動清零**,保證不重複處理;脫離 keyPressed 線程,邏輯/渲染完全可控

2. 使用前提

public class MyGameCanvas extends GameCanvas {
    public MyGameCanvas() {
        super(true); // true = 啟用 keyStates 機制
    }
    
    public void run() { // 遊戲主線程
        while (running) {
            int states = getKeyStates(); // 獲取並清零
            if ((states & LEFT_PRESSED) != 0) { /* 向左 */ }
            if ((states & RIGHT_PRESSED) != 0) { /* 向右 */ }
            // ... 更新邏輯
            repaint(); // 主動觸發渲染
            Thread.sleep(frameDelay);
        }
    }
}

3. 位掩碼常量 (GameCanvas 定義)

LEFT_PRESSED   = 1 << 0  // 0x01
RIGHT_PRESSED  = 1 << 1  // 0x02
UP_PRESSED     = 1 << 2  // 0x04
DOWN_PRESSED   = 1 << 3  // 0x08
FIRE_PRESSED   = 1 << 4  // 0x10
GAME_A_PRESSED = 1 << 5  // 0x20
GAME_B_PRESSED = 1 << 6  // 0x40
GAME_C_PRESSED = 1 << 7  // 0x80
GAME_D_PRESSED = 1 << 8  // 0x100

4. 限制條件

  • 僅限 GameCanvas 子類且構造器傳 true
  • 僅處理遊戲相關鍵 (上下左右火功能鍵);功能鍵(軟鍵/掛機)仍走 keyPressed
  • 啟用後,遊戲鍵**不再觸發** keyPressed

三、三代機制綜合對比

維度keyPressed + keyCodekeyPressed + gameActionkeyStates (GameCanvas)
MIDP 版本1.0+1.0+2.0+
線程模型系統事件線程 (EDT)系統事件線程 (EDT)遊戲主線程 (自主控制)
設備適配需處理 keyCode 差異廠商實現映射,較統一同 gameAction,標準位掩碼
邏輯/渲染分離❌ 強耦合❌ 強耦合✅ 完全分離
長按/連發處理需自行計時需自行計時✅ 位狀態持續為 1,自然支持
按鍵衝突/丟失高風險高風險低風險 (輪詢快照)
功能鍵支持✅ 全鍵盤❌ 僅遊戲鍵❌ 僅遊戲鍵 (功能鍵仍需 keyPressed)
代碼複雜度低中中高 (需管理遊戲循環)

四、最佳實踐建議

  1. 純 MIDP 1.0 設備:gameAction 映射 + 簡單狀態機,避免在 keyPressed 執行耗時邏輯
  2. MIDP 2.0 遊戲首選:繼承 GameCanvas,啟用 keyStates,構建標準遊戲循環 (輸入→邏輯→渲染→休眠)
  3. 混合模式:遊戲鍵用 keyStates,功能鍵(暫停/菜單/退出)覆蓋 keyPressed 處理
  4. 位運算封裝:定義 isPressed(states, GAME_LEFT) 工具方法,提升可讀性
  5. 幀率固定:Thread.sleep(1000 / targetFPS - elapsed) 保證穩定幀率

五、結語

從 keyPressed 的被動響應,到 gameAction 的語義映射,再到 keyStates 的主動輪詢位掩碼,**J2ME 事件處理演進本質是「控制權回歸開發者」**。MIDP 2.0 GameCanvas + keyStates 確立了移動遊戲「主循環 + 輸入快照」的工業級標準模式。現代移動遊戲引擎 (LibGDX, Cocos2d-x, Unity) 底層輸入系統同樣遵循此設計哲學。掌握三代機制本質,即掌握了跨平台遊戲輸入架構的核心邏輯。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved