延伸遊戲範例Extend the sample game

注意

本主題是使用 DirectX 教學課程系列 建立簡單通用 Windows 平臺 (UWP) 遊戲 的一部分。This topic is part of the Create a simple Universal Windows Platform (UWP) game with DirectX tutorial series. 該連結的主題會設定數列的內容。The topic at that link sets the context for the series.

現在,我們已經討論基本通用 Windows 平台 (UWP) DirectX 3D 遊戲的關鍵元件。At this point we've covered the key components of a basic Universal Windows Platform (UWP) DirectX 3D game. 您可以設定遊戲的架構,包括視圖提供者和轉譯管線,以及執行基本的遊戲迴圈。You can set up the framework for a game, including the view-provider and rendering pipeline, and implement a basic game loop. 您也可以建立基本的使用者介面重疊,並納入音效和實作控制項。You can also create a basic user interface overlay, incorporate sounds, and implement controls. 您已開始建立自己的遊戲,但如果您需要更多協助和資訊,請查看這些資源。You're on your way to creating a game of your own, but if you need more help and info, check out these resources.

用於重疊的 XAMLUsing XAML for the overlay

有一個替代方法我們沒有深入討論,那就是在重疊使用 XAML,而不使用 Direct2DOne alternative that we didn't discuss in depth is the use of XAML instead of Direct2D for the overlay. XAML 對於 Direct2D 有許多好處,可繪製使用者介面元素。XAML has many benefits over Direct2D for drawing user interface elements. 最重要的好處是結合 Windows 10 的外觀與感覺與 DirectX 遊戲且更便利。The most important benefit is that it makes incorporating the Windows 10 look and feel into your DirectX game more convenient. 許多定義 UWP 應用程式的常用元素、樣式以及行為已緊密整合到 XAML 模型,讓遊戲開發人員需要的實作的工作變得更少。Many of the common elements, styles, and behaviors that define a UWP app are tightly integrated into the XAML model, making it far less work for a game developer to implement. 如果您的遊戲設計具有很複雜的使用者介面,請考慮使用 XAML 而不要使用 Direct2D。If your own game design has a complicated user interface, consider using XAML instead of Direct2D.

使用 XAML,我們可以讓遊戲介面看起來類似 Direct2D 的舊版本。With XAML, we can make a game interface that looks similar to the Direct2D one made earlier.

XAMLXAML

XAML 重疊

Direct2DDirect2D

D2D 重疊

當有類似的最終結果時,Direct2D 與 XAML 介面間的實作也有許多差異。While they have similar end results, there are a number of differences between implementing Direct2D and XAML interfaces.

功能Feature XAMLXAML Direct2DDirect2D
定義重疊Defining overlay 已在 XAML 檔案 \*.xaml 中定義。Defined in a XAML file, \*.xaml. 一旦了解 XAML,相較於 Direct2D 建立和設定較複雜的重疊變得更容易。Once understanding XAML, creating and configuring more complicated overlays are made simpiler when compared to Direct2D. 定義為 Direct2D 基本類型的集合,而 DirectWrite 字串是手動放置和撰寫到 Direct2D 目標緩衝區。Defined as a collection of Direct2D primitives and DirectWrite strings manually placed and written to a Direct2D target buffer.
使用者介面元素User interface elements XAML 使用者介面元素來自標準化元素,它們屬於 Windows 執行階段 XAML API 的一部分,包括 Windows::UI::XamlWindows::UI::Xaml::ControlsXAML user interface elements come from standardized elements that are part of the Windows Runtime XAML APIs, including Windows::UI::Xaml and Windows::UI::Xaml::Controls. 處理 XAML 使用者介面元素行為的程式碼定義在程式碼後置檔案 Main.xaml.cpp 中。The code that handles the behavior of the XAML user interface elements is defined in a codebehind file, Main.xaml.cpp. 簡單圖形可以繪製成類似矩形和省略符號。Simple shapes can be drawn like rectangles and ellipses.
調整視窗大小Window resizing 自然地處理重新調整大小和檢視狀態變更事件,並依變更轉換重疊Naturally handles resize and view state change events, transforming the overlay accordingly 需要手動指定重新繪製重疊的元件。Need to manually specify how to redraw the overlay's components.

另一個大不相同的點包含交換鏈結Another big difference involves the swap chain. 您不必附加交換鏈結到 Windows::UI::Core::CoreWindow 物件。You don't have to attach the swap chain to a Windows::UI::Core::CoreWindow object. 相反地,在建構新的 SwapChainPanel 物件時,由納入 XAML 的 DirectX App 關聯交換鏈結。Instead, a DirectX app that incorporates XAML associates a swap chain when a new SwapChainPanel object is constructed.

下列程式碼片段顯示如何宣告 XAML 適用於 SwapChainPanel (在 DirectXPage.xaml 檔案中)。The following snippet show how to declare XAML for the SwapChainPanel in the DirectXPage.xaml file.

<Page
    x:Class="Simple3DGameXaml.DirectXPage"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:local="using:Simple3DGameXaml"
    xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
    xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
    mc:Ignorable="d">
    <SwapChainPanel x:Name="DXSwapChainPanel">

    <!-- ... XAML user controls and elements -->

    </SwapChainPanel>
</Page>

SwapChainPanel 物件設定為 App 單例在啟動 時建立的目前視窗物件的 Content 屬性。The SwapChainPanel object is set as the Content property of the current window object created at launch by the app singleton.

void App::OnLaunched(_In_ LaunchActivatedEventArgs^ /* args */)
{
    m_mainPage = ref new DirectXPage();

    Window::Current->Content = m_mainPage;
    // Bring the application to the foreground so that it's visible
    Window::Current->Activate();
}

如果要將設定的交換鏈結附加到 XAML 定義的 SwapChainPanel 執行個體,就必須取得基礎原生 ISwapChainPanelNative 介面實作的指標,並在上面呼叫 ISwapChainPanelNative::SetSwapChain,將設定的交換鏈結傳遞給它。To attach the configured swap chain to the SwapChainPanel instance defined by your XAML, you must obtain a pointer to the underlying native ISwapChainPanelNative interface implementation and call ISwapChainPanelNative::SetSwapChain on it, passing it your configured swap chain.

來自 DX::DeviceResources::CreateWindowSizeDependentResources 的下列程式碼片段詳述 DirectX/XAML interop:The following snippet from DX::DeviceResources::CreateWindowSizeDependentResources details this for DirectX/XAML interop:

        ComPtr<IDXGIDevice3> dxgiDevice;
        DX::ThrowIfFailed(
            m_d3dDevice.As(&dxgiDevice)
            );

        ComPtr<IDXGIAdapter> dxgiAdapter;
        DX::ThrowIfFailed(
            dxgiDevice->GetAdapter(&dxgiAdapter)
            );

        ComPtr<IDXGIFactory2> dxgiFactory;
        DX::ThrowIfFailed(
            dxgiAdapter->GetParent(IID_PPV_ARGS(&dxgiFactory))
            );

        // When using XAML interop, the swap chain must be created for composition.
        DX::ThrowIfFailed(
            dxgiFactory->CreateSwapChainForComposition(
                m_d3dDevice.Get(),
                &swapChainDesc,
                nullptr,
                &m_swapChain
                )
            );

        // Associate swap chain with SwapChainPanel
        // UI changes will need to be dispatched back to the UI thread
        m_swapChainPanel->Dispatcher->RunAsync(CoreDispatcherPriority::High, ref new DispatchedHandler([=]()
        {
            // Get backing native interface for SwapChainPanel
            ComPtr<ISwapChainPanelNative> panelNative;
            DX::ThrowIfFailed(
                reinterpret_cast<IUnknown*>(m_swapChainPanel)->QueryInterface(IID_PPV_ARGS(&panelNative))
                );
            DX::ThrowIfFailed(
                panelNative->SetSwapChain(m_swapChain.Get())
                );
        }, CallbackContext::Any));

        // Ensure that DXGI does not queue more than one frame at a time. This both reduces latency and
        // ensures that the application will only render after each VSync, minimizing power consumption.
        DX::ThrowIfFailed(
            dxgiDevice->SetMaximumFrameLatency(1)
            );
    }

如需這個程序的詳細資訊,請參閱 DirectX 與 XAML 互通性For more info about this process, see DirectX and XAML interop.

範例Sample

若要下載此使用 XAML 進行重迭的遊戲版本,請移至 (xaml) 的 Direct3D 診斷範例遊戲 To download the version of this game that uses XAML for the overlay, go to the Direct3D shooting sample game (XAML).

不同于這些主題其餘部分中所討論的範例遊戲版本,XAML 版本會在應用程式中定義其架構,而不是分別在DirectXPageGameInfoOverlay .cpp 檔案中定義。Unlike the version of the sample game discussed in the rest of these topics, the XAML version defines its framework in the App.xaml.cpp and DirectXPage.xaml.cpp files, instead of App.cpp and GameInfoOverlay.cpp, respectively.