Développer l’exemple de jeu

Notes

Cette rubrique fait partie de la série de tutoriels Créer un jeu de plateforme Windows universelle simple (UWP) avec DirectX. La rubrique de ce lien définit le contexte de la série.

Pour télécharger la version de ce jeu qui utilise XAML pour la superposition, consultez Exemple de jeu DirectX et XAML. Veillez à y lire le fichier readme pour plus d’informations sur la création de l’exemple.

À ce stade, nous avons couvert les composants clés d’un jeu direct 3D de base plateforme Windows universelle (UWP). Vous pouvez configurer l’infrastructure pour un jeu, y compris le pipeline de fournisseur d’affichage et de rendu, et implémenter une boucle de jeu de base. Vous pouvez également créer une superposition d’interface utilisateur de base, incorporer des sons et implémenter des contrôles. Vous êtes en train de créer votre propre jeu, mais si vous avez besoin d’aide et d’informations supplémentaires, case activée ces ressources.

Utilisation de XAML pour la superposition

Une alternative dont nous n’avons pas discuté en détail est l’utilisation de XAML au lieu de Direct2D pour la superposition. XAML présente de nombreux avantages par rapport à Direct2D pour le dessin d’éléments d’interface utilisateur. L’avantage le plus important est qu’il rend l’incorporation de l’apparence Windows 10 dans votre jeu DirectX plus pratique. Un grand nombre des éléments, styles et comportements communs qui définissent une application du Windows Store sont étroitement intégrés au modèle XAML, ce qui réduit les tâches d’implémentation d’un développeur de jeux. Si la conception de votre propre jeu a une interface utilisateur complexe, envisagez d’utiliser XAML à la place de Direct2D.

Avec XAML, nous pouvons créer une interface de jeu qui ressemble à celle de Direct2D effectuée précédemment.

XAML

Superposition XAML

Direct2D

Superposition D2D

Bien qu’ils aient des résultats finaux similaires, il existe un certain nombre de différences entre l’implémentation d’interfaces Direct2D et XAML.

Fonctionnalité XAML Direct2D
Définition de la superposition Défini dans un fichier XAML, \*.xaml. Une fois le XAML compris, la création et la configuration de superpositions plus complexes sont rendues plus simpiler par rapport à Direct2D. Défini comme une collection de primitives Direct2D et de chaînes DirectWrite placées et écrites manuellement dans une mémoire tampon cible Direct2D.
Options de l’interface utilisateur Les éléments d’interface utilisateur XAML proviennent d’éléments standardisés qui font partie des API XAML Windows Runtime, notamment Windows::UI::Xaml et Windows::UI::Xaml::Controls. Le code qui gère le comportement des éléments de l’interface utilisateur XAML est défini dans un fichier code-behind, Main.xaml.cpp. Les formes simples peuvent être dessinées comme des rectangles et des points de suspension.
Redimensionnement de fenêtre Gère naturellement les événements de changement d’état de redimensionnement et d’affichage, transformant la superposition en conséquence Vous devez spécifier manuellement comment redessiner les composants de la superposition.

Une autre grande différence concerne la chaîne d’échange. Vous n’avez pas besoin d’attacher la chaîne d’échange à un objet Windows::UI::Core::CoreWindow . Au lieu de cela, une application DirectX qui incorpore XAML associe une chaîne d’échange lorsqu’un nouvel objet SwapChainPanel est construit.

L’extrait de code suivant montre comment déclarer XAML pour SwapChainPanel dans le fichier DirectXPage.xaml .

<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>

L’objet SwapChainPanel est défini en tant que propriété Content de l’objet de fenêtre actuel créé au lancement par le singleton d’application.

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();
}

Pour attacher la chaîne d’échange configurée à l’instance SwapChainPanel défini par votre code XAML, vous devez obtenir un pointeur vers l’implémentation d’interface ISwapChainPanelNative native sous-jacente et appeler ISwapChainPanelNative::SetSwapChain, en lui transmettant votre chaîne d’échange configurée.

L’extrait de code suivant de DX::D eviceResources::CreateWindowSizeDependentResources détaille cela pour l’interopérabilité DirectX/XAML :

        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)
            );
    }

Pour plus d’informations sur ce processus, voir Technologie interop DirectX et XAML.

Exemple

Pour télécharger la version de ce jeu qui utilise XAML pour la superposition, consultez Exemple de jeu DirectX et XAML. Veillez à y lire le fichier readme pour plus d’informations sur la création de l’exemple.

Contrairement à la version de l’exemple de jeu abordé dans le reste de ces rubriques, la version XAML définit son framework dans les fichiers App.xaml.cpp et DirectXPage.xaml.cpp, au lieu d’App.cpp et GameInfoOverlay.cpp, respectivement.