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

手機遊戲開發基礎 (一):遊戲迴路、幀率鎖定與鍵盤緩衝系統

     編輯:J2ME

遊戲的三大核心模組

無論多複雜,遊戲本質只有三塊:

  1. 渲染:產生畫面
  2. 輸入:接收玩家操作
  3. 邏輯:根據輸入與狀態更新遊戲世界

兩種驅動模式:

  • 事件驅動:有輸入才更新 (典型 GUI 應用)
  • 時間驅動:無條件循環,每幀固定執行「輸入→邏輯→渲染」,專業遊戲標準模式。

最小遊戲迴路結構

0. 初始化
1. 若結束條件 → 6
2. 搜集輸入
3. 運行邏輯
4. 更新並顯示下一幀
5. 跳回 1
6. 清理資源,退出

執行緒實作遊戲迴路

讓 Canvas 實作 Runnable,在 run() 中跑迴路:

public void run() {
    boolean exit = false;
    long frameStart, frameTime;
    final int MIN_DELAY = 50; // 目標 20 FPS

    gameInit(); // 0. 初始化

    while (!exit) {
        frameStart = System.currentTimeMillis();

        acquireInput();  // 2. 輸入緩衝
        gameLoop();      // 3. 邏輯更新
        repaint();       // 4. 觸發渲染
        serviceRepaints(); // 強制立即繪製 (MIDP 2.0)

        frameTime = System.currentTimeMillis() - frameStart;
        int sleep = MIN_DELAY - (int)frameTime;
        if (sleep < 1) sleep = 1;
        try { Thread.sleep(sleep); } catch (InterruptedException e) {}
    }
    endGame(); // 6. 收尾
}

關鍵點

  • gameInit():載入資源、建立物件、重置變數。
  • acquireInput():將硬體事件轉為幀緩衝狀態 (見下)。
  • gameLoop():核心邏輯 (AI、物理、碰撞、狀態機)。
  • repaint() + serviceRepaints():雙重保證畫面更新。
  • FPS 鎖定:MIN_DELAY 設定單幀最小時間,快機睡眠、慢機全速跑,速度一致。
  • FPS 計算:1000 * 總幀數 / 總耗時 (平均值)。

專業鍵盤緩衝系統

為什麼需要緩衝?

  • keyPressed/Released 由系統執行緒呼叫,與遊戲迴路非同步。
  • 直接在回調寫邏輯會分散代碼,且無法處理「無輸入時的持續邏輯」。
  • 需判斷:長按、瞬時按下、釋放、組合鍵。

位元組旗標設計 (32 鍵上限)

// 三大狀態位圖
static int keyState = 0;       // 當前按下狀態
static int pressedState = 0;   // 本幀新按下
static int releasedState = 0;  // 本幀釋放

// 邏輯鍵位元定義
final static int KEY_UP    = 1 << 0;
final static int KEY_DOWN  = 1 << 1;
final static int KEY_LEFT  = 1 << 2;
final static int KEY_RIGHT = 1 << 3;
final static int KEY_FIRE  = 1 << 4;
// ...

系統回調寫入緩衝區

public void keyPressed(int keyCode) {
    int bit = getKeyBit(keyCode); // 硬體碼 → 邏輯位
    keyState |= bit;
    pressedState |= bit; // 記錄本幀有按下
}

public void keyReleased(int keyCode) {
    int bit = getKeyBit(keyCode);
    keyState ^= bit; // 異或清除對應位
    releasedState |= bit; // 記錄本幀有釋放
}

每幀快照 — 核心關鍵

static int frameKey, framePressed, frameReleased;

private static void acquireInput() {
    frameKey = keyState;
    framePressed = pressedState;
    frameReleased = releasedState;
    pressedState = 0;   // 清空,供下一幀收集
    releasedState = 0;
}

在 while 迴路最開頭呼叫 acquireInput(),之後邏輯只讀取快照變數,保證同一幀判斷一致。

判斷 API

// 是否長按 (含上一幀就按住)
static boolean keyHeld(int key) { return (frameKey & key) != 0; }

// 是否本幀剛按下
static boolean keyDown(int key) { return (framePressed & key) != 0; }

// 是否本幀剛釋放
static boolean keyUp(int key) { return (frameReleased & key) != 0; }

鍵碼映射函數

private static int getKeyBit(int keyCode) {
    switch (keyCode) {
        case -1: case 50: return KEY_UP;    // 不同機型實測值
        case -2: case 51: return KEY_DOWN;
        case -3: case 52: return KEY_LEFT;
        case -4: case 53: return KEY_RIGHT;
        case -5: case 10: return KEY_FIRE;
        default: return 0;
    }
}

支援多機型鍵碼,可擴展為啟動時自動偵測或玩家自定義。

總結

  1. 時間驅動迴路 + 執行緒 + FPS 鎖定 = 穩定跨平台遊戲速度。
  2. 位元組鍵盤緩衝 + 幀快照 = 專業級輸入系統,支援多鍵、長按、瞬間判斷。
  3. 此兩系統是所有 J2ME 遊戲的骨架,掌握即可著手開發實戰專案。

下一章將深入:狀態機架構、場景管理、資源載入與釋放策略。

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