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

遊戲主循環完整指南:從朴素循環到插值修正的四種模式演進

     編輯:C++ 入門

核心概念

  • 邏輯幀:`update_game()`,處理輸入、AI、物理,需**固定時間步長**。
  • 渲染幀:`display_game()`,繪製畫面,耗時不定。
  • FPS:渲染幀率。UPS:邏輯幀率(通常固定 30/60 Hz)。

四種主循環模式演進

1. 朴素循環

while (running) {
    update();
    render();
}

缺陷:忽略時間,快機器跑得飛快,慢機器跑得慢,遊戲速度與硬體綁定。

2. 固定時間步長 + Sleep

const int SKIP_TICKS = 1000 / 60;  // 60 UPS
int nextTick = GetTickCount();
while (running) {
    update();
    render();
    int sleep = nextTick - GetTickCount();
    if (sleep > 0) Sleep(sleep);
    nextTick += SKIP_TICKS;
}

優點:邏輯固定 60 Hz,錄影回放簡單(固定幀間隔)。
缺點:複雜場景渲染慢 → `update` 被延遲 → 遊戲變慢(卡頓);簡單場景 → 遊戲加速再穩定;高速物體視覺殘影(強制 60 FPS)。

3. 變時間步長

int last = GetTickCount();
while (running) {
    int now = GetTickCount();
    float dt = (now - last) / 1000.0f;
    update(dt);
    render();
    last = now;
}

優點:渲染不阻塞邏輯,硬體性能全釋放。
缺點:複雜場景 → `dt` 大 → 物理穿透、數值不穩定;不同機器浮點誤差累積導致確定性失效(回放不同步)。

4. 固定邏輯步長 + 變渲染步長 + 插值

const int TICKS = 60;           // 邏輯 60 Hz
const int SKIP = 1000 / TICKS;
const int MAX_FRAMESKIP = 5;    // 最大追趕幀數

int nextTick = GetTickCount();
int loops;
float interpolation;

while (running) {
    loops = 0;
    while (GetTickCount() > nextTick && loops < MAX_FRAMESKIP) {
        update();
        nextTick += SKIP;
        loops++;
    }
    interpolation = float(GetTickCount() + SKIP - nextTick) / SKIP;
    render(interpolation);
}

優點:
- 邏輯**絕對固定 60 Hz**,物理穩定、確定性回放。
- 渲染**盡可能快**,高端機器享受高 FPS。
- **插值修正**:渲染時刻落在兩個邏輯幀之間,用 `interpolation` (0~1) 線性插值位置:
`view_pos = old_pos + (new_pos - old_pos) * interpolation`。
高速物體平滑移動,無殘影。
- 超過 `MAX_FRAMESKIP` 才真正降低邏輯頻率(遊戲變慢),保護低端機不死機。

插值原理圖解

邏輯幀:  [10]----[11]----[12]----[13]  (固定 16.67ms 間隔)
渲染時刻:       ↑ t=10.3
插值因子:  0.3
渲染位置:  pos10 + (pos11 - pos10) * 0.3

需在 `render(interpolation)` 內對所有可視物體應用插值預測位置。

模式選擇建議

場景推薦模式理由
手機/嵌入式/固定硬體模式 2 (固定步長+Sleep)省電、實現簡單、行為確定
PC/主機大型遊戲模式 4 (固定邏輯+插值渲染)物理穩定、高幀率平滑、確定性回放
簡單 2D/原型/不需回放模式 3 (變時間步長)代碼最少、硬體性能全用
教學/極簡 Demo模式 1理解概念用,實戰禁用

關鍵代碼片段:插值渲染

void render(float interp) {
    for (auto& obj : objects) {
        // obj.oldPos 上一邏輯幀位置,obj.pos 當前邏輯幀位置
        Vec2 viewPos = obj.oldPos + (obj.pos - obj.oldPos) * interp;
        drawSprite(obj.sprite, viewPos);
    }
}

// 邏輯幀更新時保存舊位置
void update() {
    for (auto& obj : objects) {
        obj.oldPos = obj.pos;
        obj.pos += obj.vel * FIXED_DT;  // 固定時間步長
    }
}

總結

**模式 4(固定邏輯步長 + 插值渲染)是工業級遊戲主循環的標準答案**。它同時滿足:物理確定性、高幀率視覺平滑、高低端硬體適應性、錄影回放確定性。唯一成本是需在渲染層實現插值預測,但收益遠大於成本。

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