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

MFC 飛機大戰長按鍵盤導致畫面卡頓:降低事件處理頻率

     編輯:程式設計綜合問答

MFC 遊戲中長按方向鍵/發射鍵導致畫面卡頓,根因是鍵盤重複觸發率過高(通常 30-50 次/秒),邏輯處理與繪圖跟不上。本文給出降頻與優化方案。

問題代碼模式

void OnTimer(UINT nID) {
  if (GetKeyState(VK_SPACE) & 0x8000) { // 長按空格
    FireBullet(); // 每次定時器都創建子彈、加入列表
  }
  // 移動鍵同理
}

解決方案:節流/降頻

  1. 設置最小發射間隔:
    DWORD m_lastFireTime = 0;
    void FireBulletThrottled() {
      DWORD now = GetTickCount();
      if (now - m_lastFireTime >= 200) { // 最快 5 發/秒
        m_lastFireTime = now;
        FireBullet();
      }
    }
  2. 移動鍵邊界檢查:到達邊界後停止處理移動邏輯,避免無效計算
  3. 遊戲循環固定幀率:定時器間隔設為 16ms (≈60FPS) 或 33ms (≈30FPS),邏輯更新與渲染分離

bool 標志位用法修正

原問題中的 ismybullet 應在「子彈實際發射後」重置,而非按鍵按下時:

if (GetKeyState(VK_SPACE) & 0x8000 && !ismybullet) {
  ismybullet = true;
  FireBulletThrottled(); // 內部按間隔創建子彈
  // ismybullet = false; // ❌ 不要這裡重置
}
// 在 FireBulletThrottled 內部按間隔允許時:
// ismybullet = false; // ✅ 實際發射後重置,允許下一次

繪圖優化

  • 雙緩衝已使用(良好)
  • 僅繪制可視區域內對象(裁剪)
  • 子彈/敵機列表定期清理超出屏幕/銷毀的對象
  • 考慮 CImageList 替換逐幀 BitBlt

總結

遊戲主循環要「固定時間步長 + 邏輯與渲染分離」,輸入處理要「節流 + 邊界裁剪」,卡頓自然消失。

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