Delen via


Het gameproject instellen

Opmerking

Dit onderwerp maakt deel uit van de tutorialreeks Een eenvoudig Universal Windows Platform (UWP) spel maken met DirectX. In het onderwerp op die koppeling wordt de context voor de reeks ingesteld.

De eerste stap bij het ontwikkelen van uw game is het maken van een project in Microsoft Visual Studio. Nadat u een project specifiek hebt geconfigureerd voor gameontwikkeling, kunt u het later opnieuw gebruiken als een soort sjabloon.

Doelstellingen

  • Maak een nieuw project in Visual Studio met behulp van een projectsjabloon.
  • Begrijp het toegangspunt en de initialisatie van de game door het bronbestand van de App-klasse te bekijken.
  • Kijk eens naar de game loop.
  • Bekijk het bestand package.appxmanifest van het project.

Een nieuw project maken in Visual Studio

Opmerking

Voor informatie over het instellen van Visual Studio voor C++/WinRT-ontwikkeling, waaronder het installeren en gebruiken van de C++/WinRT Visual Studio-extensie (VSIX) en het NuGet-pakket (die samen ondersteuning bieden voor projectsjablonen en de build), zie Visual Studio-ondersteuning voor C++/WinRT.

Installeer (of werk bij naar) de nieuwste versie van de C++/WinRT Visual Studio-extensie (VSIX); zie de bovenstaande opmerking. Maak vervolgens in Visual Studio een nieuw project op basis van de C++/WinRT-projectsjabloon (Core App ). Richt u op de meest recente algemeen beschikbare (dat wil gezegd, niet preview) versie van de Windows SDK.

Bekijk de app-klasse om inzicht te hebben in IFrameworkViewSource en IFrameworkView

Open in uw Core App-project het broncodebestand App.cpp. Er is de implementatie van de App-klasse, die de app en diens levenscyclus vertegenwoordigt. In dit geval weten we natuurlijk dat de app een spel is. Maar we verwijzen ernaar als een app om over het algemeen te praten over hoe een UWP-app (Universal Windows Platform) initialiseert.

De functie wWinMain

De functie wWinMain is het toegangspunt voor de app. Zo ziet wWinMain eruit (van App.cpp).

int __stdcall wWinMain(HINSTANCE, HINSTANCE, PWSTR, int)
{
    CoreApplication::Run(winrt::make<App>());
}

We maken een exemplaar van de App-klasse (dit is de ene en enige instantie van de app die is gemaakt) en we geven dat door aan de statische CoreApplication.Run-methode . CoreApplication.Run verwacht een IFrameworkViewSource-interface. De App-klasse moet die interface dus implementeren.

In de volgende twee secties in dit onderwerp worden de IFrameworkViewSource - en IFrameworkView-interfaces beschreven. Deze interfaces (evenals CoreApplication.Run) vormen een manier waarop uw app Windows kan leveren met een weergaveprovider. Windows gebruikt die view-provider om uw app te verbinden met de Windows-shell, zodat u levenscyclusgebeurtenissen van toepassingen kunt afhandelen.

De IFrameworkViewSource-interface

De app-klasse implementeert inderdaad IFrameworkViewSource, zoals u kunt zien in de onderstaande lijst.

struct App : winrt::implements<App, IFrameworkViewSource, IFrameworkView>
{
    ...
    IFrameworkView CreateView()
    {
        return *this;
    }
    ...
}

Een object dat IFrameworkViewSource- implementeert, is een -object van de weergaveprovider. Het object is bedoeld om een view-provider-object te produceren en te retourneren.

IFrameworkViewSource heeft de enige methode IFrameworkViewSource::CreateView. Windows roept die functie aan op het object dat u doorgeeft aan CoreApplication.Run. Zoals u hierboven kunt zien, retourneert de App::CreateView-implementatie van die methode *this. Met andere woorden, het App-object retourneert zichzelf. Omdat IFrameworkViewSource::CreateView een retourwaardetype IFrameworkView heeft, volgt het dat de App-klassedie interface ook moet implementeren. En u kunt zien dat het zich in de bovenstaande lijst toont.

De IFrameworkView-interface

Een object dat IFrameworkView implementeert, is een object van de weergaveprovider . En we hebben nu die view-provider aan Windows geleverd. Het is hetzelfde App-object dat we in wWinMain hebben gemaakt. De App-klasse fungeert dus zowel als view-provider factory als als view-provider.

Windows kan nu de implementaties van de app-klasse aanroepen van de methoden van IFrameworkView. In de implementaties van deze methoden krijgt uw app de kans om taken uit te voeren, zoals initialiseren, te beginnen met het laden van de benodigde resources, de juiste gebeurtenis-handlers aan te sluiten en de CoreWindow- te ontvangen waarmee uw app de uitvoer zal weergeven.

Uw implementaties van de methoden van IFrameworkView worden aangeroepen in de onderstaande volgorde.

Hier is het skelet van de App-klasse (in App.cpp), waarin de signaturen van die methoden worden getoond.

struct App : winrt::implements<App, IFrameworkViewSource, IFrameworkView>
{
    ...
    void Initialize(Windows::ApplicationModel::Core::CoreApplicationView const& applicationView) { ... }
    void SetWindow(Windows::UI::Core::CoreWindow const& window) { ... }
    void Load(winrt::hstring const& entryPoint) { ... }
    void OnActivated(
        Windows::ApplicationModel::Core::CoreApplicationView const& applicationView,
        Windows::ApplicationModel::Activation::IActivatedEventArgs const& args) { ... }
    void Run() { ... }
    void Uninitialize() { ... }
    ...
}

Dit was slechts een inleiding tot IFrameworkView. We gaan veel meer in op deze methoden en hoe we ze implementeren, in het UWP-app-framework van de game definiëren.

Het project opruimen

Het Core App-project dat u hebt gemaakt op basis van de projectsjabloon bevat functionaliteit die op dit moment moet worden opgegeruimd. Daarna kunnen we het project gebruiken om het schietgaleriespel (Simple3DGameDX) opnieuw te maken. Breng de volgende wijzigingen aan in de App-klasse in App.cpp.

  • Verwijder de gegevensleden.
  • Verwijder OnPointerPressed, OnPointerMoved, en AddVisual
  • Verwijder de code uit SetWindow.

Het project wordt gebouwd en uitgevoerd, maar er wordt alleen een effen kleur weergegeven in het clientgebied.

De gameloop

Als u een idee wilt krijgen van hoe een gamelus eruitziet, kijkt u in de broncode voor het Simple3DGameDX-voorbeeldspel dat u hebt gedownload.

De app-klasse heeft een gegevenslid met de naam m_main van het type GameMain. En dat element wordt op deze manier gebruikt in App::Run.

void Run()
{
    m_main->Run();
}

U vindt GameMain::Run in GameMain.cpp. Het is de belangrijkste cyclus van het spel, en hier is een zeer ruw overzicht waarin de belangrijkste functies worden getoond.

void GameMain::Run()
{
    while (!m_windowClosed)
    {
        if (m_visible)
        {
            CoreWindow::GetForCurrentThread().Dispatcher().ProcessEvents(CoreProcessEventsOption::ProcessAllIfPresent);
            Update();
            m_renderer->Render();
            m_deviceResources->Present();
        }
        else
        {
            CoreWindow::GetForCurrentThread().Dispatcher().ProcessEvents(CoreProcessEventsOption::ProcessOneAndAllPending);
        }
    }
}

En hier is een korte beschrijving van wat deze hoofdspel lus doet.

Als het venster voor uw game niet is gesloten, verzendt u alle gebeurtenissen, werkt u de timer bij en geeft u de resultaten van de grafische pijplijn weer en presenteert u deze. Er is nog veel meer te zeggen over deze problemen. Dit doen we in de onderwerpen Definiëren het UWP-app-framework, renderingframework I: Inleiding tot rendering en Rendering framework II: Game rendering. Maar dit is de basiscodestructuur van een UWP DirectX-game.

Het bestand package.appxmanifest controleren en bijwerken

Het bestand Package.appxmanifest bevat metagegevens over een UWP-project. Deze metagegevens worden gebruikt voor het verpakken en starten van uw game en voor verzending naar de Microsoft Store. Het bestand bevat ook belangrijke informatie die het systeem van de speler gebruikt om toegang te bieden tot de systeembronnen die het spel moet uitvoeren.

Start de manifestontwerper door te dubbelklikken op het bestand Package.appxmanifest in Solution Explorer.

schermopname van de package.appx manifesteditor.

Zie Manifest Designer voor meer informatie over het package.appxmanifest-bestand en de verpakking. Bekijk nu het tabblad Mogelijkheden en bekijk de beschikbare opties.

schermopname met de standaardmogelijkheden van een direct3d-app.

Als u niet de mogelijkheden selecteert die uw game gebruikt, zoals toegang tot internet voor een wereldwijd hoog scorebord, hebt u geen toegang tot de bijbehorende resources of functies. Wanneer u een nieuwe game maakt, moet u ervoor zorgen dat u alle mogelijkheden selecteert die nodig zijn voor API's die door uw game worden aangeroepen.

Laten we nu eens kijken naar de rest van de bestanden die worden geleverd met de Simple3DGameDX-voorbeeldgame .

Andere belangrijke bibliotheken en broncodebestanden controleren

Als u van plan bent een soort gameprojectsjabloon voor uzelf te maken, zodat u dit kunt hergebruiken als uitgangspunt voor toekomstige projecten, wilt u GameMain.h en GameMain.cpp uit het Simple3DGameDX--project dat u gedownload hebt kopiëren en deze toevoegen aan uw nieuwe Core App-project. Onderzoek die bestanden, leer wat ze doen en verwijder alles wat specifiek is voor Simple3DGameDX. Markeer ook alles wat afhankelijk is van code die u nog niet hebt gekopieerd. Bij wijze van voorbeeld, GameMain.h is afhankelijk van GameRenderer.h. U kunt opmerkingen verwijderen wanneer u meer bestanden kopieert uit Simple3DGameDX.

Hier volgt een korte enquête van enkele bestanden in Simple3DGameDX die u nuttig vindt om op te nemen in uw sjabloon, als u er een maakt. In ieder geval zijn dit even belangrijk om te begrijpen hoe Simple3DGameDX zelf werkt.

Bronbestand Map Beschrijving
DeviceResources.h/.cpp Nutsvoorzieningen Hiermee definieert u de klasse DeviceResources , waarmee alle DirectX-apparaatresources worden bepaald. Definieert ook de IDeviceNotify-interface , die wordt gebruikt om uw toepassing op de hoogte te stellen dat het apparaat van de grafische adapter verloren is gegaan of opnieuw is gemaakt.
DirectXSample.h Nutsvoorzieningen Hiermee worden helperfuncties zoals ConvertDipsToPixelsgeïmplementeerd. ConvertDipsTo Pixels converteert een lengte in apparaatonafhankelijke pixels (DIPs) naar een lengte in fysieke pixels.
GameTimer.h/.cpp Nutsvoorzieningen Definieert een timer met hoge resolutie die handig is voor gaming- of interactieve rendering-apps.
GameRenderer.h/.cpp Renderen Definieert de GameRenderer-klasse , waarmee een eenvoudige rendering-pijplijn wordt geïmplementeerd.
GameHud.h/.cpp Renderen Definieert een klasse voor het weergeven van een hoofdscherm (HUD) voor het spel, met behulp van Direct2D en DirectWrite.
VertexShader.hlsl en VertexShaderFlat.hlsl Schaduwtechnologieën Bevat de HLSL-code (High-Level Shader Language) voor eenvoudige hoekpunt-shaders.
PixelShader.hlsl en PixelShaderFlat.hlsl Schaduwtechnologieën Bevat de HLSL-code (High Level Shader Language) voor pixel-shaders.
ConstantBuffers.hlsli Schaduwtechnologieën Bevat definities van gegevensstructuren voor constante buffers en shaderstructuren die worden gebruikt om MVP-matrices (model-view-projection) en per hoekpuntgegevens door te geven aan de hoekpunt-shader.
pch.h/.cpp Niet van toepassing. Bevat veelvoorkomende C++/WinRT-, Windows- en DirectX-inclusies.

Volgende stappen

Op dit moment hebben we laten zien hoe we een nieuw UWP-project voor een DirectX-game kunnen maken, een aantal onderdelen hierin hebben bekeken en begonnen te denken over het omzetten van dat project in een soort herbruikbare sjabloon voor games. We hebben ook enkele van de belangrijke onderdelen van het Simple3DGameDX-voorbeeldspel bekeken.

De volgende sectie is het UWP-app-framework van de game definiëren. Daar kijken we nader naar hoe Simple3DGameDX werkt.