Hinweis
Für den Zugriff auf diese Seite ist eine Autorisierung erforderlich. Sie können versuchen, sich anzumelden oder das Verzeichnis zu wechseln.
Für den Zugriff auf diese Seite ist eine Autorisierung erforderlich. Sie können versuchen, das Verzeichnis zu wechseln.
In diesem Thema werden die grundlegenden Merkmale des Marble Maze-Projekts beschrieben, z. B. wie Visual C++ in der Windows-Runtime-Umgebung verwendet wird, wie es erstellt und strukturiert wird und wie es erstellt wird. Im Thema werden auch einige der Konventionen beschrieben, die im Code verwendet werden.
Hinweis
Der Beispielcode, der diesem Dokument entspricht, befindet sich im DirectX Marble Maze-Spielbeispiel.
Hier sind einige der wichtigsten Punkte, die in diesem Dokument erläutert werden, wenn Sie Ihr UWP-Spiel (Universelle Windows-Plattform) planen und entwickeln.
- Verwenden Sie die DirectX 11-Anwendung (Universelle Windows-Plattform - C++/CX) Vorlage in Visual Studio, um Ihr DirectX-UWP-Spiel zu erstellen.
- Die Windows-Runtime stellt Klassen und Schnittstellen bereit, damit Sie UWP-Apps auf modernere, objektorientierte Weise entwickeln können.
- Verwenden Sie Objektverweise mit dem Hutsymbol (^), um die Lebensdauer von Windows-Runtime-Variablen zu verwalten, Microsoft::WRL::ComPtr, um die Lebensdauer von COM-Objekten zu verwalten, und std::shared_ptr oder std::unique_ptr, um die Lebensdauer aller anderen im Heap zugewiesenen C++-Objekte zu verwalten.
- Verwenden Sie in den meisten Fällen die Ausnahmebehandlung anstelle von Ergebniscodes, um unerwartete Fehler zu behandeln.
- Verwenden Sie SAL-Anmerkungen zusammen mit Codeanalysetools, um Fehler in Ihrer App zu erkennen.
Erstellen des Visual Studio-Projekts
Wenn Sie das Beispiel heruntergeladen und extrahiert haben, können Sie die MarbleMaze_VS2017.sln Datei (im C++ -Ordner) in Visual Studio öffnen, und Sie haben den Code vor Ihnen.
Als wir das Visual Studio-Projekt für Marble Maze erstellt haben, haben wir mit einem vorhandenen Projekt begonnen. Wenn Sie jedoch noch nicht über ein Vorhandenes Projekt verfügen, das die grundlegenden Funktionen bereitstellt, die Ihr DirectX-UWP-Spiel erfordert, empfehlen wir, ein Projekt basierend auf der Visual Studio DirectX 11-App-Vorlage (Universal Windows - C++/CX) zu erstellen, da sie eine einfache 3D-Anwendung bereitstellt. Gehen Sie dazu wie folgt vor:
Wählen Sie in Visual Studio 2019 Datei > Neues > Projekt aus...
Wählen Sie im Fenster Erstellen eines neuen Projekts die Option DirectX 11-App (Universelle Windows-App - C++/CX)aus. Wenn diese Option nicht angezeigt wird, sind möglicherweise nicht die erforderlichen Komponenten installiert. Weitere Informationen zum Installieren zusätzlicher Komponenten finden Sie unter "Ändern von Visual Studio 2019", indem Sie Arbeitslasten und Komponenten hinzufügen oder entfernen .
- Wählen Sie Weiteraus, und geben Sie dann einen Projektnamen, einen Speicherort für die zu speichernden Dateien und einen Lösungsnameein, und wählen Sie dann Erstellenaus.
Eine wichtige Projekteinstellung in der DirectX 11-App (Universal Windows-App – C++/CX) Vorlage ist die Option /ZW, die es dem Programm ermöglicht, die Windows-Runtime-Spracherweiterungen zu verwenden. Diese Option ist standardmäßig aktiviert, wenn Sie die Visual Studio-Vorlage verwenden. Für weitere Informationen darüber, wie Sie Compileroptionen in Visual Studio festlegen, siehe Compiler- und Linkeroptionen (C++/CX).
Vorsicht Die Option /ZW ist nicht mit anderen Optionen wie zum Beispiel /clrkompatibel. Im Fall von "/clr" bedeutet dies, dass Sie sowohl das .NET Framework als auch die Windows-Runtime nicht aus demselben Visual C++-Projekt als Ziel verwenden können.
Jede UWP-App, die Sie aus dem Microsoft Store erwerben, wird in Form eines App-Pakets bereitgestellt. Ein App-Paket enthält ein Paketmanifest, das Informationen zu Ihrer App enthält. Sie können beispielsweise die Funktionen (d. h. den erforderlichen Zugriff auf geschützte Systemressourcen oder Benutzerdaten) Ihrer App angeben. Wenn Sie feststellen, dass Ihre App bestimmte Funktionen benötigt, verwenden Sie das Paketmanifest, um die erforderlichen Funktionen zu deklarieren. Mit dem Manifest können Sie auch Projekteigenschaften wie unterstützte Bildschirmdrehungen, Kachelbilder und den Startbildschirm angeben. Sie können das Manifest bearbeiten, indem Sie Package.appxmanifest in Ihrem Projekt öffnen. Weitere Informationen zu App-Paketen finden Sie unter Verpacken von Apps.
Erstellen, Bereitstellen und Ausführen des Spiels
Wählen Sie in den Dropdownmenüs oben in Visual Studio links neben der grünen Wiedergabeschaltfläche Ihre Bereitstellungskonfiguration aus. Es wird empfohlen, sie als Debug- für die Architektur Ihres Geräts festzulegen (x86- für 32-Bit, x64- für 64-Bit) und auf Ihren lokalen Computer. Sie können auch auf einem Remotecomputeroder auf einem Gerät testen, das über USB angeschlossen ist. Klicken Sie dann auf die grüne Wiedergabeschaltfläche, um zu kompilieren und auf Ihrem Gerät bereitzustellen.
des lokalen Computers
Steuern des Spiels
Sie können Toucheingabe, Beschleunigungsmesser, Einen Gamecontroller oder die Maus verwenden, um Marble Maze zu steuern.
- Verwenden Sie das Steuerkreuz auf dem Controller, um das aktive Menüelement zu ändern.
- Verwenden Sie die Toucheingabe, die A- oder Starttaste auf dem Controller oder die Maus, um ein Menüelement zu wählen.
- Verwenden Sie Touch, den Beschleunigungsmesser, den linken Daumenstick oder die Maus, um das Labyrinth zu neigen.
- Verwenden Sie die Toucheingabe, die A- oder Starttaste auf dem Controller oder die Maus, um Menüs wie die Highscore-Tabelle zu schließen.
- Verwenden Sie die Starttaste auf dem Controller oder die P-Taste auf der Tastatur, um das Spiel anzuhalten oder fortzusetzen.
- Verwenden Sie die Zurück-Taste auf dem Controller oder die START-TASTE auf der Tastatur, um das Spiel neu zu starten.
- Wenn die Highscore-Tabelle sichtbar ist, verwenden Sie die Zurück-Taste auf dem Controller oder die Home-Taste auf der Tastatur, um alle Punktzahlen zu löschen.
Codekonventionen
Die Windows-Runtime ist eine Programmierschnittstelle, mit der Sie UWP-Apps erstellen können, die nur in einer speziellen Anwendungsumgebung ausgeführt werden. Solche Apps verwenden autorisierte Funktionen, Datentypen und Geräte und werden aus dem Microsoft Store verteilt. Auf der niedrigsten Ebene besteht die Windows-Runtime aus einem Anwendungsbinärschnittstelle (ABI). Die ABI ist ein binärer Vertrag auf niedriger Ebene, der Windows-Runtime-APIs für mehrere Programmiersprachen wie JavaScript, .NET-Sprachen und Visual C++ zugänglich macht.
Um Windows-Runtime-APIs aus JavaScript und .NET aufzurufen, benötigen diese Sprachen Projektionen, die für jede Sprachumgebung spezifisch sind. Wenn Sie eine Windows-Runtime-API aus JavaScript oder .NET aufrufen, rufen Sie die Projektion auf, die wiederum die zugrunde liegende ABI-Funktion aufruft. Obwohl Sie die ABI-Funktionen direkt in C++ aufrufen können, stellt Microsoft auch Projektionen für C++ bereit, da sie die Verwendung der Windows-Runtime-APIs erheblich vereinfachen und gleichzeitig eine hohe Leistung gewährleisten. Microsoft stellt auch Spracherweiterungen für Visual C++ bereit, die speziell die Windows-Runtime-Projektionen unterstützen. Viele dieser Spracherweiterungen ähneln der Syntax für die C++/CLI-Sprache. Jedoch verwenden systemeigene Apps anstelle der Common Language Runtime (CLR) diese Syntax für die Windows-Runtime. Der Objektverweis oder Hat (^) Modifikator ist ein wichtiger Bestandteil dieser neuen Syntax, da er das automatische Löschen von Laufzeitobjekten mittels Verweiszählung ermöglicht. Anstatt Methoden wie AddRef und Release aufzurufen, um die Lebensdauer eines Windows-Runtime-Objekts zu verwalten, löscht die Laufzeit das Objekt, wenn keine andere Komponente darauf verweist, z. B. wenn sie den Bereich verlässt oder Sie alle Verweise auf nullptr festlegen. Ein weiterer wichtiger Bestandteil bei der Verwendung von Visual C++ zum Erstellen von UWP-Apps ist das Schlüsselwort ref new. Verwenden Sie verweis neue anstelle neuen, um referenzierte Windows-Runtime-Objekte zu erstellen. Weitere Informationen finden Sie unter Type System (C++/CX).
Von Bedeutung
Sie müssen ^ und neuen nur verwenden, wenn Sie Windows-Runtime-Objekte erstellen oder Komponenten für Windows-Runtime erstellen. Sie können die C++-Standardsyntax verwenden, wenn Sie Kernanwendungscode schreiben, der die Windows-Runtime nicht verwendet.
Marble Maze verwendet ^ zusammen mit Microsoft::WRL::ComPtr, um heap-zugeordnete Objekte zu verwalten und Speicherverluste zu minimieren. Es wird empfohlen, ^ zu verwenden, um die Lebensdauer von Windows-Runtime-Variablen zu verwalten, ComPtr zur Verwaltung der Lebensdauer von COM-Variablen (z. B. bei Verwendung von DirectX), und std::shared_ptr oder std::unique_ptr, um die Lebensdauer aller anderen heap-zugeordneten C++-Objekte zu verwalten.
Weitere Informationen zu den Spracherweiterungen, die für eine C++-UWP-App verfügbar sind, finden Sie unter Visual C++-Sprachreferenz (C++/CX).
Fehlerbehandlung
Marble Maze verwendet die Ausnahmebehandlung als primäre Methode zum Umgang mit unerwarteten Fehlern. Obwohl der Spielcode traditionell Protokollierungs- oder Fehlercodes verwendet, z. B. HRESULT-Werte , um Fehler anzuzeigen, hat die Ausnahmebehandlung zwei Hauptvorteile. Zunächst kann der Code einfacher zu lesen und zu verwalten sein. Aus Codeperspektive ist die Ausnahmebehandlung eine effizientere Möglichkeit, einen Fehler an eine Routine zu verteilen, die diesen Fehler behandeln kann. Die Verwendung von Fehlercodes erfordert in der Regel, dass jede Funktion Fehler explizit weiterleitet. Ein zweiter Vorteil besteht darin, dass Sie den Visual Studio-Debugger so konfigurieren können, dass er unterbrochen wird, wenn eine Ausnahme auftritt, sodass Sie sofort an der Position und dem Kontext des Fehlers anhalten können. Die Windows-Runtime verwendet auch eine umfangreiche Ausnahmebehandlung. Daher können Sie mit der Ausnahmebehandlung in Ihrem Code alle Fehlerbehandlungen in einem Modell kombinieren.
Es wird empfohlen, die folgenden Konventionen in Ihrem Fehlerbehandlungsmodell zu verwenden:
Verwenden Sie Ausnahmen, um unerwartete Fehler zu kommunizieren.
Verwenden Sie keine Ausnahmen, um den Codefluss zu steuern.
Erfassen Sie nur die Ausnahmen, die Sie sicher behandeln und wiederherstellen können. Andernfalls können Sie die Ausnahme nicht abfangen und der App das Beenden gestatten.
Wenn Sie eine DirectX-Routine aufrufen, die HRESULT-zurückgibt, verwenden Sie die funktion DX::ThrowIfFailed. Diese Funktion wird in DirectXHelper.h definiert. ThrowIfFailed löst eine Ausnahme aus, wenn der bereitgestellte HRESULT ein Fehlercode ist. Beispielsweise bewirkt E_POINTER, dass durch ThrowIfFailed eine Platform::NullReferenceExceptionausgelöst wird.
Wenn Sie ThrowIfFailedverwenden, setzen Sie den DirectX-Aufruf in eine separate Zeile, um die Lesbarkeit des Codes zu verbessern, wie im folgenden Beispiel gezeigt.
// Identify the physical adapter (GPU or card) this device is running on. ComPtr<IDXGIAdapter> dxgiAdapter; DX::ThrowIfFailed( dxgiDevice->GetAdapter(&dxgiAdapter) );
Obwohl wir empfehlen, die Verwendung von HRESULT- für unerwartete Fehler zu vermeiden, ist es noch wichtiger, auf die Verwendung von Ausnahmebehandlung zur Steuerung des Codeflusses zu verzichten. Daher wird es bevorzugt, einen HRESULT-Rückgabewert zu verwenden, wenn erforderlich, um den Codefluss zu steuern.
SAL-Anmerkungen
Verwenden Sie SAL-Anmerkungen zusammen mit Codeanalysetools, um Fehler in Ihrer App zu erkennen.
Mithilfe der Microsoft-Quellcodeanmerkungssprache (SOURCE-Code Annotation Language, SAL) können Sie kommentieren oder beschreiben, wie eine Funktion ihre Parameter verwendet. SAL-Anmerkungen beschreiben auch Rückgabewerte. SAL-Anmerkungen arbeiten mit dem C/C++-Codeanalysetool zusammen, um mögliche Fehler im C- und C++-Quellcode zu ermitteln. Häufige Codierungsfehler, die vom Tool gemeldet werden, umfassen Pufferüberläufe, nicht initialisierten Speicher, Nullzeiger-Dereferenzierungen und Speicher- und Ressourcenverluste.
Betrachten Sie die BasicLoader::LoadMesh-Methode , die in BasicLoader.h deklariert ist. Diese Methode verwendet _In_
, um anzugeben, dass Dateiname ein Eingabeparameter ist (und daher nur gelesen wird), _Out_
um anzugeben, dass VertexBuffer und IndexBuffer Ausgabeparameter sind (und daher nur beschrieben werden), und _Out_opt_
um anzugeben, dass VertexCount und IndexCount optionale Ausgabeparameter sind (und möglicherweise beschrieben werden können). Da vertexCount und indexCount optionale Ausgabeparameter sind, dürfen sie nullptrsein. Das C/C++-Codeanalysetool untersucht Aufrufe dieser Methode, um sicherzustellen, dass die übergebenen Parameter diese Kriterien erfüllen.
void LoadMesh(
_In_ Platform::String^ filename,
_Out_ ID3D11Buffer** vertexBuffer,
_Out_ ID3D11Buffer** indexBuffer,
_Out_opt_ uint32* vertexCount,
_Out_opt_ uint32* indexCount
);
Um eine Code-Analyse für Ihre App durchzuführen, wählen Sie auf der Menüleiste Build > Code-Analyse auf Lösung ausführenaus. Weitere Informationen zur Codeanalyse finden Sie unter Analysieren der C/C++-Codequalität mithilfe der Codeanalyse.
Die vollständige Liste der verfügbaren Anmerkungen wird in sal.h definiert. Weitere Informationen finden Sie unter SAL Annotations.
Nächste Schritte
Lesen Sie die Marble Maze-Anwendungsstruktur , um Informationen darüber zu erhalten, wie der Marble Maze-Anwendungscode strukturiert ist und wie sich die Struktur einer DirectX-UWP-App von der einer herkömmlichen Desktopanwendung unterscheidet.
Zugehörige Themen