Anteckning
Åtkomst till den här sidan kräver auktorisering. Du kan prova att logga in eller ändra kataloger.
Åtkomst till den här sidan kräver auktorisering. Du kan prova att ändra kataloger.
Anmärkning
Det här avsnittet är en del av Skapa ett enkelt UWP-spel (Universal Windows Platform) med DirectX självstudieserie. Ämnet på länken anger kontexten för serien.
Det första steget i att utveckla ditt spel är att skapa ett projekt i Microsoft Visual Studio. När du har konfigurerat ett projekt specifikt för spelutveckling kan du senare återanvända det som en slags mall.
Målsättningar
- Skapa ett nytt projekt i Visual Studio med hjälp av en projektmall.
- Förstå spelets startpunkt och initiering genom att undersöka källfilen för appklassen .
- Titta på spelloopen.
- Granska projektets package.appxmanifest-fil .
Skapa ett nytt projekt i Visual Studio
Anmärkning
Information om hur du konfigurerar Visual Studio för C++/WinRT-utveckling– inklusive installation och användning av C++/WinRT Visual Studio-tillägget (VSIX) och NuGet-paketet (som tillsammans tillhandahåller projektmall och byggstöd)– finns i Visual Studio-stöd för C++/WinRT-.
Installera först (eller uppdatera till) den senaste versionen av VSIX (C++/WinRT Visual Studio Extension). se anteckningen ovan. I Visual Studio skapar du sedan ett nytt projekt baserat på projektmallen Core App (C++/WinRT). Rikta in dig på den senaste allmänt tillgängliga (dvs. inte förhandsversionen) av Windows SDK.
Granska appklassen för att förstå IFrameworkViewSource och IFrameworkView
Öppna källkodsfilen App.cppi ditt Core App-projekt. Där finns implementeringen av klassen App, som representerar appen och dess livscykel. I det här fallet vet vi naturligtvis att appen är ett spel. Men vi refererar till den som en app för att kunna prata mer allmänt om hur en UWP-app (Universal Windows Platform) initieras.
Funktionen wWinMain
Funktionen wWinMain är startpunkten för appen. Så här ser wWinMain ut (från App.cpp).
int __stdcall wWinMain(HINSTANCE, HINSTANCE, PWSTR, int)
{
CoreApplication::Run(winrt::make<App>());
}
Vi gör en instans av klassen App (det här är den enda instansen av app som har skapats), och vi skickar den till metoden static CoreApplication.Run . Observera att CoreApplication.Run förväntar sig ett IFrameworkViewSource-gränssnitt . Appklassen måste därför implementera det gränssnittet.
Följande två avsnitt i det här avsnittet beskriver gränssnitten IFrameworkViewSource och IFrameworkView . Dessa gränssnitt (samt CoreApplication.Run) är ett sätt för din app att förse Windows med en visningsprovider. Windows använder den vyprovidern för att ansluta din app till Windows-gränssnittet så att du kan hantera programlivscykelhändelser.
Gränssnittet i IFrameworkViewSource
Appklassen implementerar verkligen IFrameworkViewSource, som du kan se i listan nedan.
struct App : winrt::implements<App, IFrameworkViewSource, IFrameworkView>
{
...
IFrameworkView CreateView()
{
return *this;
}
...
}
Ett objekt som implementerar IFrameworkViewSource är ett view-provider-fabriksobjekt . Objektets uppgift är att tillverka och returnera en visningsprovider objekt.
IFrameworkViewSource har den enda metoden IFrameworkViewSource::CreateView. Windows anropar den funktionen på det objekt som du skickar till CoreApplication.Run. Som du ser ovan returnerar App::CreateView-implementeringen av den metoden *this. Med andra ord returnerar appobjektet sig självt. Eftersom IFrameworkViewSource::CreateView har en returvärdetyp av IFrameworkView, följer det att appklassen också måste implementera gränssnittet . Och du kan se att det gör det i listan ovan.
IFrameworkView-gränssnittet
Ett objekt som implementerar IFrameworkView är ett visningsproviderobjekt . Och nu har vi försett Windows med den visningsprovidern. Det är samma App objekt som vi skapade i wWinMain. Klassen App fungerar därför som både view-provider factory och view-provider.
Nu kan Windows anropa appklassens implementeringar av metoderna för IFrameworkView. I implementeringarna av dessa metoder har din app möjlighet att utföra uppgifter som initiering, att börja läsa in de resurser den behöver, att ansluta lämpliga händelsehanterare och att ta emot den CoreWindow som appen använder för att visa utdata.
Dina implementeringar av metoderna för IFrameworkView anropas i den ordning som visas nedan.
- Initiera
- Ställ in fönster
- Läs in
- Händelsen CoreApplicationView::Activated genereras. Så om du (valfritt) har registrerat dig för att hantera händelsen anropas din OnActivated-hanterare just nu.
- Kör
- Avinitiera
Och här är skelettet av klassen App (i App.cpp), som visar signaturerna för dessa metoder.
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() { ... }
...
}
Detta var bara en introduktion till IFrameworkView. Vi går in på mycket mer information om dessa metoder och hur du implementerar dem i Definiera spelets UWP-appramverk.
Städa upp projektet
Core App-projektet som du skapade från projektmallen innehåller funktioner som vi bör uppdatera nu. Därefter kan vi använda projektet för att återskapa skjutgallerispelet (Simple3DGameDX). Gör följande ändringar i klassen App i App.cpp.
- Ta bort dess datamedlemmar.
- Ta bort OnPointerPressed, OnPointerMovedoch AddVisual
- Ta bort koden från SetWindow.
Projektet kommer att kompileras och köras, men det kommer bara att visa en enhetlig färg i klientområdet.
Spelloopen
För att få en uppfattning om hur en spelloop ser ut, titta i källkoden för Simple3DGameDX-exempelspelet som du laddade ned.
Klassen App har en datamedlem med namnet m_main av typen GameMain. Och den används i App::Run på följande sätt.
void Run()
{
m_main->Run();
}
Du hittar GameMain::Run i GameMain.cpp. Det är huvudslingan i spelet, och här är en mycket grov beskrivning av det som visar de viktigaste funktionerna.
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);
}
}
}
Och här är en kort beskrivning av vad den här huvudspelsloopen gör.
Om fönstret för ditt spel inte är stängt, hantera alla händelser, uppdatera timern och rendera och presentera sedan resultaten av grafikrörledningen. Det finns mycket mer att säga om dessa problem, och vi kommer att göra det i ämnena Definiera spelets UWP-appramverk, Renderingsramverk I: Introduktion till rendering och Rendering framework II: Spelrendering. Men det här är den grundläggande kodstrukturen i ett UWP DirectX-spel.
Granska och uppdatera filen package.appxmanifest
Filen Package.appxmanifest innehåller metadata om ett UWP-projekt. Dessa metadata används för att paketera och starta ditt spel och för att skicka till Microsoft Store. Filen innehåller också viktig information som spelarens system använder för att ge åtkomst till de systemresurser som spelet behöver köra.
Starta manifestdesignern genom att dubbelklicka på filen Package.appxmanifest i Solution Explorer.
Mer information om filen och paketeringen package.appxmanifest finns i Manifestdesigner. För tillfället tar du en titt på fliken Funktioner och tittar på de alternativ som tillhandahålls.
Om du inte väljer de funktioner som ditt spel använder, till exempel åtkomst till Internet för global högpoängstavla, kommer du inte att kunna komma åt motsvarande resurser eller funktioner. När du skapar ett nytt spel kontrollerar du att du väljer de funktioner som krävs av API:er som ditt spel anropar.
Nu ska vi titta på resten av filerna som medföljer Simple3DGameDX-exempelspelet .
Granska andra viktiga bibliotek och källkodsfiler
Om du tänker skapa en typ av spelprojektmall för dig själv, så att du kan återanvända den som startpunkt för framtida projekt, så vill du kopiera GameMain.h och GameMain.cpp ut från Simple3DGameDX-projektet som du laddade ned och lägga till dem i ditt nya Core App-projekt. Studera dessa filer, lär dig vad de gör och ta bort allt som är specifikt för Simple3DGameDX. Kommentera även ut allt som är beroende av kod som du ännu inte har kopierat. Som ett exempel, GameMain.h beror på GameRenderer.h. Du kommer att kunna avkommentera medan du kopierar fler filer från Simple3DGameDX.
Här är en kort undersökning av några av filerna i Simple3DGameDX som du kan ta med i mallen om du gör en. I vilket fall som helst är dessa lika viktiga för att förstå hur Simple3DGameDX själv fungerar.
| Källfil | Mapp | Beskrivning |
|---|---|---|
| DeviceResources.h/.cpp | Tjänster | Definierar klassen DeviceResources , som styr alla DirectX-enhetsresurser. Definierar även IDeviceNotify-gränssnittet , som används för att meddela ditt program att grafikkortets enhet har förlorats eller återskapats. |
| DirectXSample.h | Tjänster | Implementerar hjälpfunktioner som ConvertDipsToPixels. ConvertDipsToPixels konverterar en längd i enhetsoberoende bildpunkter (DIP:er) till en längd i fysiska bildpunkter. |
| GameTimer.h/.cpp | Tjänster | Definierar en timer med hög upplösning som är användbar för spel eller interaktiva renderingsappar. |
| GameRenderer.h/.cpp | återgivning | Definierar klassen GameRenderer , som implementerar en grundläggande återgivningspipeline. |
| GameHud.h/.cpp | återgivning | Definierar en klass för att rendera en heads up-skärm (HUD) för spelet med Direct2D och DirectWrite. |
| VertexShader.hlsl och VertexShaderFlat.hlsl | skuggare | Innehåller HLSL-koden (high-level shader language) för grundläggande hörnskuggor. |
| PixelShader.hlsl och PixelShaderFlat.hlsl | skuggare | Innehåller HLSL-koden (high-level shader language) för grundläggande pixelskuggare. |
| ConstantBuffers.hlsli | skuggare | Innehåller datastrukturdefinitioner för konstantbuffertar och skuggningsstrukturer som används för att skicka MVP-matriser (model-view-projection) och per-vertex-data till hörnskuggaren. |
| pch.h/.cpp | Inte tillgänglig | Innehåller vanliga C++/WinRT-, Windows- och DirectX-inkluderingar. |
Nästa steg
Nu har vi visat hur du skapar ett nytt UWP-projekt för ett DirectX-spel, tittat på några av delarna i det och börjat fundera på hur du omvandlar projektet till en slags återanvändbar mall för spel. Vi har också tittat på några av de viktiga delarna i Simple3DGameDX-exempelspelet .
Nästa avsnitt är Definiera spelets UWP-appramverk. Där tittar vi närmare på hur Simple3DGameDX fungerar.