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

bada 2D 遊戲開發(四):遊戲主迴圈設計全攻略——從幀ベース到固定時間步長

     編輯:關於C語言

核心概念釐清

  • 幀:單一遊戲畫面,連續幀形成動畫
  • 幀間隔:相鄰兩幀顯示時間差(毫秒)
  • 幀率 FPS:每秒顯示幀數,即 Draw() 呼叫頻率
  • 遊戲速率:每秒邏輯更新次數,即 UpdateLogic() 呼叫頻率

三種主流迴圈實作演進

1. 幀ベース迴圈

while(isRunning) {
    HandleEvent();
    UpdateLogic(); // 固定步長,如每幀移動 1 像素
    Draw();
}

缺陷:不同效能裝置上幀間隔不同,導致遊戲速度不一致。高效能裝置 20ms/幀 → 50 次更新/秒,低效能 50ms/幀 → 20 次更新/秒,同一角色單位時間位移差 2.5 倍。

2. 可變時間步長

引入實際幀時間 frameTime 為參數,位移 = 速度 × 時間:

lastFrameTime = GetCurrentTime();
while(isRunning) {
    currentFrameTime = GetCurrentTime();
    frameTime = currentFrameTime - lastFrameTime;
    HandleEvent();
    UpdateLogic(frameTime);
    Draw();
    lastFrameTime = currentFrameTime;
}

解決:不同裝置速度一致。新問題:frameTime 波動大時(如 CPU 被佔用),碰撞檢測頻率下降,導致高速物體「穿牆」。且迴圈持續佔用 CPU。

3. 固定時間步長——推薦方案

設定目標幀率(如 40 FPS → 25ms/幀),邏輯使用固定 FRAME_TIME,渲染盡力而為,剩餘時間 sleep 釋放 CPU:

const int FRAME_RATE = 40;
const long FRAME_TIME = 1000 / FRAME_RATE;

while(isRunning) {
    startTime = GetCurrentTime();
    HandleEvent();
    UpdateLogic(); // 邏輯回歸固定步長,無需乘時間
    Draw();
    endTime = GetCurrentTime();
    deltaTime = endTime - startTime - FRAME_TIME;
    if(deltaTime > 0) sleep(deltaTime);
    else { /* 處理超時:略過渲染或多步更新 */ }
}

優勢:邏輯確定性、CPU 友善、碰撞檢測穩定。若需更高碰撞精度,可在單幀內多次呼叫 UpdateLogic()(邏輯速率 > 幀率)。

進階變體

分離渲染與邏輯頻率、引入插值渲染平滑畫面、多執行緒架構等,均以固定時間步長為基礎延伸。

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