Porter la boucle de jeu

Résumé

Montre comment implémenter une fenêtre pour un jeu de plateforme Windows universelle (UWP) et comment récupérer la boucle de jeu, notamment comment créer une interface IFrameworkView pour contrôler une classe CoreWindow en plein écran. Partie 3 de la procédure pas à pas Porter une application Direct3D 9 simple vers DirectX 11 et UWP.

Créer une fenêtre

Pour configurer une fenêtre de bureau avec une fenêtre d’affichage Direct3D 9, nous devions implémenter l’infrastructure de fenêtrage traditionnelle des applications de bureau. Nous devions créer un HWND, définir la taille de la fenêtre, fournir un rappel de traitement de fenêtre, le rendre visible, etc.

L’environnement UWP possède un système beaucoup plus simple. Au lieu de configurer une fenêtre traditionnelle, un jeu du Microsoft Store à l’aide de DirectX implémente IFrameworkView. Cette interface existe pour que les applications et les jeux DirectX s’exécutent directement dans un CoreWindow à l’intérieur du conteneur d’application.

Remarque Windows fournit des pointeurs gérés aux ressources tels que l’objet d’application source et la classe CoreWindow. Consultez Handle to Object Operator (^).

 

Votre « principale » classe doit hériter de l’interface IFrameworkView et implémenter les cinq méthodes IFrameworkView : Initialize, SetWindow, Load, Run et Uninitialize. En plus de créer l’interface IFrameworkView, qui correspond (essentiellement) à l’emplacement auquel votre jeu va résider, vous devez implémenter une classe de fabrique qui crée une instance de votre interface IFrameworkView. Votre jeu possède quand même un exécutable avec une méthode appelée main(), mais celle-ci peut uniquement utiliser la fabrique pour créer l’instance IFrameworkView.

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

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

Porter la boucle de jeu

Examinons la boucle de jeu de notre implémentation Direct3D 9. Ce code existe dans la fonction main de l’application. Chaque itération de cette boucle traite un message de fenêtre ou génère le rendu d’une image.

Boucle de jeu dans un jeu sur ordinateur 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();
    }
}

La boucle de jeu est similaire, mais plus facile, dans la version UWP de notre jeu :

La boucle de jeu va dans la méthode IFrameworkView::Run (plutôt que main()) car notre jeu fonctionne au sein de la classe IFrameworkView.

Au lieu d’implémenter une infrastructure de gestion des messages et d’appeler PeekMessage, nous pouvons appeler la méthode ProcessEvents intégrée au CoreDispatcher de notre fenêtre d’application. La boucle de jeu n’a pas besoin de se ramifier et de gérer les messages : il suffit d’appeler la méthode ProcessEvents et de continuer.

Boucle de jeu dans Le Microsoft Store Direct3D 11

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

Nous avons à présent une application UWP qui configure la même infrastructure graphique de base, et génère le rendu du même cube haut en couleur que celui de notre exemple DirectX 9.

Étapes suivantes

Marquez d’un signet le Forum Aux Questions (FAQ) sur le portage DirectX 11.

Les modèles UWP DirectX incluent une infrastructure de périphérique Direct3D robuste prête à l’emploi avec votre jeu UWP. Pour obtenir des conseils sur la sélection du modèle approprié, voir Créer un projet de jeu DirectX à partir d’un modèle.

Consultez les articles détaillés suivants sur le développement de jeux du Microsoft Store :