【问题标题】:Designing the game loop设计游戏循环
【发布时间】:2021-05-17 08:34:43
【问题描述】:

我正在开发一个简单的 Win 游戏。这是我的 2 个类似的游戏循环实现(在 C++ 中):

方法#1:

while (Msg.message != WM_QUIT) {

        if (PeekMessage(&Msg, NULL, 0, 0, PM_REMOVE) > 0) {
            TranslateMessage(&Msg);
            DispatchMessage(&Msg);
        }
        else {
            // Do update, rendering and all the real game loop stuff
        }
}

方法#2:

while (Msg.message != WM_QUIT) {

        if (PeekMessage(&Msg, NULL, 0, 0, PM_REMOVE) > 0) {
            TranslateMessage(&Msg);
            DispatchMessage(&Msg);
        }
        
        // Do update, rendering and all the real game loop stuff
        
}}

我的问题是哪个更好,我应该选择哪个?是像#1 方法那样在 else 闭包中进行更新和渲染内容,还是像 #2 方法那样仅在 while 循环块中进行更新和渲染?

【问题讨论】:

  • 读取消息的目的是什么 - 处理消息,直到它存在于队列中
  • 第二个循环总是会增加延迟。消息到达的频率通常(远)高于呈现频率。虽然您可能会看到硬件光标移动,但它只是在稍后的时间,您的代码会观察输入。这会带来相当滞后的体验。

标签: c++ windows winapi visual-c++


【解决方案1】:

答案完全取决于用例。

在您的第一种方法中,您在更新游戏状态之前处理队列中的所有消息。这可能会让您避免一些由较新消息过时的旧消息引发的更新。

但是,在负载很重的队列中,这可能会导致您的应用程序反应不佳甚至冻结。

第二种方法通过始终更新游戏状态来避免这种情况。

第一种方法可能会变得更健壮 e。 G。只允许在强制更新之前处理最大数量的消息。

【讨论】:

  • 对不起,但您似乎错了-'在您的第二种方法中,您在更新游戏状态之前处理队列中的任何消息'-我认为这是第一种方法,因为游戏更新和渲染包含在 else 语句中...
  • 这源于您编辑问题之前的while - 承认,我自己也忽略了其他问题。调整答案。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2013-07-26
  • 1970-01-01
  • 2014-01-21
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-04-11
相关资源
最近更新 更多