移植游戏循环

摘要

介绍如何实现通用 Windows 平台 (UWP) 游戏的窗口,以及如何显示游戏循环,包括如何构建 IFrameworkView 来控制全屏 CoreWindow将简单的 Direct3D 9 应用移植到 DirectX 11 和 UWP 操作实例的第 3 部分。

创建窗口

若要设置一个具有 Direct3D 9 视区的桌面窗口,我们必须为桌面应用实现传统的窗口框架。 必须创建 HWND、设置窗口大小、 提供窗口处理回调、使其可见等。

UWP 环境具有更简单的系统。 不再设置传统的窗口,Microsoft Store 游戏使用 DirectX 实现 IFrameworkView。 对于要直接在应用容器内的 CoreWindow 中运行的 DirectX 应用和游戏来说,存在该接口。

注意 Windows 提供指向资源(如源应用程序对象和 CoreWindow)的托管指针。 请参阅对象句柄运算符 (^)

 

你的“main”类需要从 IFrameworkView 继承并且实现五种 IFrameworkView 方法:InitializeSetWindowLoadRunUninitialize。 除了创建 IFrameworkView(从本质上说,这是你的游戏所在的位置)之外,你还需要实现一个用于创建 IFrameworkView 实例的工厂类。 你的游戏仍然包含一个可执行文件,该文件具有一个名为 main() 的方法,但所有 main 均可以使用工厂来创建 IFrameworkView 实例。

main 函数

//-----------------------------------------------------------------------------
// Required method for a DirectX-only app.
// The main function is only used to initialize the app's IFrameworkView class.
//-----------------------------------------------------------------------------
[Platform::MTAThread]
int main(Platform::Array<Platform::String^>^)
{
    auto direct3DApplicationSource = ref new Direct3DApplicationSource();
    CoreApplication::Run(direct3DApplicationSource);
    return 0;
}

IFrameworkView 工厂

//-----------------------------------------------------------------------------
// This class creates our IFrameworkView.
//-----------------------------------------------------------------------------
ref class Direct3DApplicationSource sealed : 
    Windows::ApplicationModel::Core::IFrameworkViewSource
{
public:
    virtual Windows::ApplicationModel::Core::IFrameworkView^ CreateView()
    {
        return ref new Cube11();
    };
};

移植游戏循环

下面我们看一看 Direct3D 9 实现中的游戏循环。 该代码位于应用的 main 函数中。 该循环的每次迭代都处理一个窗口消息或呈现一个帧。

Direct3D 9 桌面游戏中的游戏循环

while(WM_QUIT != msg.message)
{
    // Process window events.
    // Use PeekMessage() so we can use idle time to render the scene. 
    bGotMsg = (PeekMessage(&msg, NULL, 0U, 0U, PM_REMOVE) != 0);

    if(bGotMsg)
    {
        // Translate and dispatch the message
        TranslateMessage(&msg);
        DispatchMessage(&msg);
    }
    else
    {
        // Render a new frame.
        // Render frames during idle time (when no messages are waiting).
        RenderFrame();
    }
}

该游戏循环非常相似 - 但在游戏的 UWP 版本中却更加简单:

游戏循环进入 IFrameworkView::Run 方法(而不是 main()),因为我们的游戏在 IFrameworkView 类中起作用。

不再实现消息处理框架和调用 PeekMessage,我们可以调用为我们的应用窗口的 CoreDispatcher 构建的 ProcessEvents 方法。 游戏循环无需分流和处理消息 - 只需调用 ProcessEvents 并继续。

Direct3D 11 Microsoft Store 游戏中的游戏循环

// UWP apps should not exit. Use app lifecycle events instead.
while (true)
{
    // Process window events.
    auto dispatcher = CoreWindow::GetForCurrentThread()->Dispatcher;
    dispatcher->ProcessEvents(CoreProcessEventsOption::ProcessAllIfPresent);

    // Render a new frame.
    RenderFrame();
}

现在,我们已经拥有一个 UWP 应用,该应用设置与我们的 DirectX 9 示例相同的基本图形基础结构并呈现相同的彩色立方体。

我此时该如何操作?

DirectX 11 移植 FAQ 创建书签。

DirectX UWP 模板包含可随时与游戏结合使用的强大 Direct3D 设备基础结构。 有关选取正确模板的指南,请参阅从模板创建 DirectX 游戏项目

请访问下列做深入阐述的 Microsoft Store 游戏开发文章: