Marble Maze 示例基础知识
本文档介绍 Marble Maze 项目的基本特征,例如,它如何在 Windows 运行时环境中使用 Visual C++,如何创建和构造它以及如何生成它。本文档还介绍了代码中使用的几种约定。
说明
|
|---|
|
对应于本文档的示例代码可在 DirectX marble maze 游戏示例中找到。 |
下面是本文档针对您规划和开发 Windows 应用商店游戏所讨论的一些要点。
-
在 C++ 应用程序中使用“Direct3D 应用程序”模板创建您的 DirectX Windows 应用商店游戏。使用 Visual Studio 生成 Windows 应用商店应用程序项目,就像生成标准项目一样。
-
Windows 运行时提供类和接口,以便您可以采用更现代化的面向对象的方式开发 Windows 应用商店应用程序。
-
使用具有乘幂号 (^) 的对象引用来管理 Windows 运行时变量的生存期,使用 Microsoft::WRL::ComPtr 来管理 COM 对象的生存期,使用 std::shared_ptr 或 std::unique_ptr 来管理所有其他堆分配的 C++ 对象的生存期。
-
在大多数情况下,使用异常处理而不是结果代码来处理意外错误。
-
结合使用 SAL 注释和代码分析工具来帮助发现应用程序中的错误。
以下几节更详细地介绍了这些要点。
如果您已下载并解压缩示例,则可以在 Visual Studio 中打开 MarbleMaze.sln 解决方案文件,代码将显示在您的面前。还可以在 DirectX marble maze 游戏示例 MSDN 样本库页上通过选择“浏览代码”选项卡来查看源。
在我们为 Marble Maze 创建了 Visual Studio 项目时,我们从现有项目开始。但是,如果您还没有提供了您的 DirectX Windows 应用商店游戏所需的基本功能的现有项目,建议您基于 Visual Studio“Direct3D 应用程序”模板创建项目,因为它提供基本运行的三维应用程序。
“Direct3D 应用程序”模板中的一个重要项目设置是 /ZW 选项,它使程序能够使用 Windows 运行时语言扩展。默认情况下,在您使用 Visual Studio 模板时,此选项处于启用状态。
警告
|
|---|
|
/ZW 选项与 /clr 之类的选项不兼容。如果使用 /clr,这意味着不能让同一 Visual C++ 项目同时面向 .NET Framework 和 Windows 运行时。 |
您从 Windows 应用商店 获取的每个 Windows 应用商店应用程序采用应用程序包 的形式。应用程序包包含包清单,其中包含有关您的应用程序的信息。例如,可以指定您的应用程序的功能(即,对受保护系统资源或用户数据的必需访问权限)。如果您确定应用程序需要某些功能,请使用包清单来声明所需的功能。清单还允许您指定项目属性(例如支持的设备旋转、磁贴图像和初始屏幕)。有关应用程序包的更多信息,请参见App packages and deployment。
[顶部]
生成 Windows 应用商店应用程序项目,就像生成标准项目一样。(在菜单栏上,选择“生成”、“生成解决方案”。)生成步骤编译代码,还将其打包以用作 Windows 应用商店应用程序。
在生成项目后,必须部署它。(在菜单栏上,选择“生成”、“部署解决方案”。)Visual Studio 还在您从调试器运行游戏时部署项目。
在部署项目后,选取 Marble Maze 磁贴来运行游戏。或者,从 Visual Studio 中的菜单栏上选择“调试”、“启动调试”。
控制游戏
可以使用触摸屏、加速计、Xbox 360 控制器或鼠标来控制 Marble Maze。
-
使用控制器上的方向键来更改活动菜单项。
-
使用触摸屏、A 按钮、“开始”按钮或鼠标来选取菜单项。
-
使用触摸屏、加速计、左摇杆或鼠标来倾斜迷宫。
-
使用触摸屏、A 按钮、“开始”按钮或鼠标来关闭菜单,例如高分表。
-
使用“开始”按钮或 P 键来暂停或继续游戏。
-
使用控制器上的“返回”按钮或键盘上的 Home 键来重新启动游戏。
-
当高分表可见时,使用“返回”按钮或 Home 键来清除所有分数。
[顶部]
Windows 运行时是一个编程接口,可用于创建仅在特殊应用程序环境中运行的 Windows 应用商店应用程序。此类应用程序使用授权的功能、数据类型和设备,并从 Windows 应用商店分发。在最低级别上,Windows 运行时包括应用程序二进制接口 (ABI)。ABI 是一种低级二进制协定,使 Windows 运行时 API 可供多种编程语言(例如 JavaScript、.NET 语言和 Visual C++)访问。
为了从 JavaScript 和 .NET 调用 Windows 运行时 API,这些语言需要特定于每种语言环境的投影。当您从 JavaScript 或 .NET 调用 Windows 运行时 API 时,您将调用投影,投影又调用基础 ABI 函数。虽然可以直接在 C++ 中调用 ABI 函数,但 Microsoft 也为 C++ 提供了投影,因为利用投影,可以更简单地使用 Windows 运行时 API,同时仍保持高性能。Microsoft 还为 Visual C++ 提供了专门支持 Windows 运行时投影的语言扩展。其中许多语言扩展类似于 C++/CLI 语言的语法。但是,本机应用程序使用此语法来面向 Windows 运行时,而不是面向公共语言运行时 (CLR)。对象引用或者乘幂号 (^) 修饰符是此新语法的重要部分,因为它通过引用计数启用了运行时对象的自动删除。不是调用方法(例如 AddRef 和 Release)来管理 Windows 运行时对象的生存期,运行时会在其他任何组件都不引用该对象时(例如,在它离开范围或您将所有引用设置为 nullptr 时)删除该对象。使用 Visual C++ 创建 Windows 应用商店应用程序的另一个重要部分是 ref new 关键字。使用 ref new 而不是 new 创建引用计数的 Windows 运行时对象。有关更多信息,请参见类型系统 (C++/CX)。
重要事项
|
|---|
|
仅在创建 Windows 运行时对象或创建 Windows 运行时组件时,才必须使用 ^ 和 ref new。在编写不使用 Windows 运行时的核心应用程序代码时,可以使用标准 C++ 语法。 Marble Maze 结合使用 ^ 和 Microsoft::WRL::ComPtr 来管理堆分配的对象和最小化内存泄漏。建议您使用 ^ 来管理 Windows 运行时变量的生存期,使用 ComPtr 来管理 COM 变量的生存期(例如,在使用 DirectX 时),使用 std::shared_ptr 或 std::unique_ptr 来管理所有其他堆分配的 C++ 对象的生存期。 |
有关可供 C++ Windows 应用商店应用程序使用的语言扩展的更多信息,请参见 Visual C++ 语言参考 (C++/CX)。有关 Windows 运行时 API 的更多信息,请参见 Windows 应用商店应用程序的 Windows API 参考。
错误处理
Marble Maze 使用异常处理作为处理意外错误的主要方式。虽然游戏代码传统上使用日志记录或错误代码(例如 HRESULT 值)来指示错误,但异常处理有两个主要优点。首先,它可使代码更易于读取和维护。从代码角度看,异常处理是将错误传播到可处理该错误的例程的更高效方法。使用错误代码通常要求每个函数显式传播错误。第二个优点是可以将 Visual Studio 调试器配置为在发生异常时中断,以便可以在发生错误的位置和上下文立即停止。Windows 运行时也广泛使用异常处理。因此,通过在代码中使用异常处理,可以将所有错误处理合并为一个模型。
建议您在错误处理模型中使用以下约定:
-
使用异常来传递意外错误。
-
不要使用异常来控制代码流。
-
仅捕获您可以安全处理和恢复的异常。否则,不要捕获异常,并允许应用程序终止。
-
当您调用返回 HRESULT 的 DirectX 例程时,请使用 DX::ThrowIfFailed 函数。此函数是在 DirectXSample.h 中定义的。如果提供的 HRESULT 是错误代码,则 ThrowIfFailed 将引发异常。例如,E_POINTER 导致 ThrowIfFailed 引发 Platform::NullReferenceException。
当您使用 ThrowIfFailed 时,请将 DirectX 调用放在单独的行上以帮助提高代码可读性,如下面的示例所示。
// Identify the physical adapter (GPU or card) this device is running on. ComPtr<IDXGIAdapter> dxgiAdapter; DX::ThrowIfFailed( dxgiDevice->GetAdapter(&dxgiAdapter) ); -
虽然建议您避免对意外错误使用 HRESULT,但避免使用异常处理来控制代码流更为重要。因此,最好在需要时使用 HRESULT 返回值来控制代码流。
SAL 注释
结合使用 SAL 注释和代码分析工具来帮助发现应用程序中的错误。
通过使用 Microsoft 源代码注释语言 (SAL),可以注释或描述函数如何使用其参数。SAL 注释还描述返回值。SAL 注释使用 C/C++ 代码分析工具来发现 C 和 C++ 源代码中可能存在的缺陷。工具报告的常见编码错误包括缓冲区溢出、内存未初始化、null 指针取消引用以及内存和资源泄漏。
考虑在 BasicLoader.h 中声明的 BasicLoader::LoadMesh 方法。此方法使用 _In_ 来指定 filename 是输入参数(因此将只从其中读取),使用 _Out_ 来指定 vertexBuffer 和 indexBuffer 是输出参数(因此将只向其写入),并且使用 _Out_opt_ 来指定 vertexCount 和 indexCount 是可选的输出参数(可能向其写入)。因为 vertexCount 和 indexCount 是可选的输出参数,所以允许它们为 nullptr。C/C++ 代码分析工具检查对此方法的调用来确保它传递的参数满足这些条件。
void LoadMesh(
_In_ Platform::String^ filename,
_Out_ ID3D11Buffer** vertexBuffer,
_Out_ ID3D11Buffer** indexBuffer,
_Out_opt_ uint32* vertexCount,
_Out_opt_ uint32* indexCount
);
若要对您的应用程序执行代码分析,请在菜单栏上,选择“生成”、“对解决方案运行代码分析”。有关代码分析的更多信息,请参见使用代码分析来分析 C/C++ 代码质量。
在 sal.h 中定义了可用注释的完整列表。有关 SAL 注释的更多信息,请参见 SAL注释。
[顶部]
阅读 Marble Maze 应用程序结构来了解有关如何构造 Marble Maze 应用程序代码,以及 DirectX Windows 应用商店应用程序的结构与传统桌面应用程序的结构有何不同的信息。
[顶部]
说明
警告