延伸遊戲範例

注意

本主題屬於<使用 DirectX 建立簡單的通用 Windows 平台 (UWP) 遊戲>教學課程系列的一部分。 該連結主題是提供這系列教學的基本背景介紹。

若要下載此使用 XAML 進行重疊的遊戲版本,請參閱<DirectX 和 XAML 遊戲範例>。 請務必閱讀「讀我檔案」,以取得建置範例的詳細資料。

截至目前,我們已介紹了基本通用 Windows 平台 (UWP) DirectX 3D 遊戲的主要元件。 您可設定遊戲的架構,包括 view-provider 和轉譯管線,以及實作基本遊戲迴圈。 您也可以建立基本使用者介面重疊、整合音效,以及實作控制項。 您已經可以開始建立自己的遊戲,但若需要更多協助和資訊,歡迎參閱這些資源。

使用 XAML 進行重疊

除了使用 Direct2D 進行重疊,還有一個替代方案是使用 XAML,這部分我們尚未詳細介紹。 就繪製使用者介面元素而言,使用 XAML 的優點比 DIRECT2D 更多。 最大的優點是更方便將 Windows 10 的外觀和風格融入 DirectX 遊戲。 許多用來定義 UWP 應用程式的常見元素、樣式和行為都已緊密整合至 XAML 模型,可大幅減少遊戲開發人員的實作工作。 如果您自己的遊戲設計採用複雜的使用者介面,請考慮使用 XAML 而不是 Direct2D。

透過 XAML 可建立與稍早 Direct2D 介面類似的遊戲介面。

XAML

XAML overlay

Direct2D

D2D overlay

雖然最終結果類似,但 Direct2D 和 XAML 介面兩者實作起來仍有許多差異。

功能 XAML Direct2D
定義重疊 在 XAML 檔案 \*.xaml 中定義。 瞭解 XAML 之後,建立和設定複雜重疊會比使用 Direct2D 更容易。 定義為 Direct2D 基本類型的集合,DirectWrite 字串則手動放置並寫入至 Direct2D 目標緩衝區。
使用者介面元素 XAML 使用者介面元素源自標準化元素 (屬於 Windows 執行階段 XAML API),包含 Windows::UI::XamlWindows::UI::Xaml::Controls。 處理 XAML 使用者介面元素行為的程式碼,是在程式碼後置檔案 Main.xaml.cpp 中定義。 簡單的圖形可繪製為矩形和橢圓。
視窗大小調整 自然處理大小調整和檢視狀態變更事件,並據以轉換重疊 需要手動指定如何重新繪製重疊的元件。

另一個重要差異則涉及交換鏈結。 您不需要將交換鏈結附加至 Windows::UI::Core::CoreWindow 物件。 建構新的 SwapChainPanel 物件時,已整合 XAML 的 DirectX 應用程式就會與交換鏈結建立關聯。

下方程式碼片段示範如何在 DirectXPage.xaml 檔案中為 XAML 宣告 SwapChainPanel

<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 物件設為目前視窗物件的 Content 屬性 (該視窗物件是由應用程式單例模式在啟動時建立的)。

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,以將其傳遞至已設定的交換鏈結。

下方 DX::DeviceResources::CreateWindowSizeDependentResources 的程式碼片段會針對 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 interop>。

範例

若要下載此使用 XAML 進行重疊的遊戲版本,請參閱<DirectX 和 XAML 遊戲範例>。 請務必閱讀「讀我檔案」,以取得建置範例的詳細資料。

不同於其餘主題中討論的範例遊戲版本,XAML 版本是分別在 App.xaml.cppDirectXPage.xaml.cpp 檔案中定義其架構,而不是 App.cppGameInfoOverlay.cpp