J2ME 遊戲要求按鍵響應靈敏、跨機型兼容。直接在 keyPressed/keyReleased 編寫邏輯會導致響應延遲且難以移植。本文介紹一種基於位運算的按鍵狀態機制,分離按鍵記錄與邏輯處理,支持自定義鍵值映射。
private int keyStates; // 每個 bit 代表一個按鍵狀態:1=按下, 0=釋放
自定義按鍵常量(每個佔一個 bit 位):
public static final int KEY_UP = 1 << 0; // 0x01
public static final int KEY_DOWN = 1 << 1; // 0x02
public static final int KEY_LEFT = 1 << 2; // 0x04
public static final int KEY_RIGHT = 1 << 3; // 0x08
public static final int KEY_FIRE = 1 << 4; // 0x10
// 可擴展更多按鍵...
不同手機物理鍵碼不同,需映射為統一自定義值。以 WTK 模擬器為例:
private int translateKey(int keyCode) {
switch (keyCode) {
case Canvas.UP: return KEY_UP;
case Canvas.DOWN: return KEY_DOWN;
case Canvas.LEFT: return KEY_LEFT;
case Canvas.RIGHT: return KEY_RIGHT;
case Canvas.FIRE: return KEY_FIRE;
// 某些機型需額外映射數字鍵等
default: return 0;
}
}
protected void keyPressed(int keyCode) {
int key = translateKey(keyCode);
if (key != 0) {
keyStates |= key; // 位或操作置位
}
}
protected void keyReleased(int keyCode) {
int key = translateKey(keyCode);
if (key != 0) {
keyStates &= ~key; // 位與取反清零
}
}
public void resetKeyStates() {
keyStates = 0; // 一次性清空所有按鍵狀態
}
public void run() {
while (running) {
// 檢測按鍵狀態
if ((keyStates & KEY_LEFT) != 0) { /* 向左移動 */ }
if ((keyStates & KEY_RIGHT) != 0) { /* 向右移動 */ }
if ((keyStates & KEY_FIRE) != 0) { /* 發射子彈 */ }
// 組合鍵檢測
if ((keyStates & (KEY_UP | KEY_FIRE)) == (KEY_UP | KEY_FIRE)) { /* 跳躍攻擊 */ }
// 遊戲邏輯更新、重繪...
try { Thread.sleep(20); } catch (Exception e) {}
}
}
translateKey() 適配新機型鍵碼。