Android Game Development Extension 的範例示範如何使用這個擴充功能的主要功能。本主題對於範例以及執行這些功能所需的設定加以說明。
以下是下載頁面上提供的範例:
- HelloJNI:一款入門專案。
- Endless-Tunnel:一款僅適用於 Android 的專案。
- Teapot:一款適用於 Windows 和 Android 的跨平台專案。
- AssemblyCode-Link-Objects:含有組合原始碼的範本專案。
事前準備
安裝 Android Game Development Extension 和範例。詳情請參閱快速入門導覽課程。這個主題也會說明如何建構及執行範例,該範例是採用 Android 版本的 Teapot 範例。
專案設定指南說明如何針對採用擴充功能的專案調整設定,例如新增 Android 平台和 APK。
HelloJNI
HelloJNI 範例是一個簡單的專案,會在應用程式視窗中顯示「Hello From JNI」訊息。這個專案針對 Windows 和 Android 使用一組不同的原始碼。
- Android 原始碼和 Gradle 建構指令碼目錄:HelloJNI\AndroidPackaging
- Windows 原始碼和 Visual Studio 專案目錄:HelloJNI
建構專案時,Visual Studio 會將下列設定傳送至應用程式層級的 build.gradle
檔案。您可以修改 Gradle 建構指令碼來變更這些設定。
MSBUILD_NDK_VERSION
MSBUILD_MIN_SDK_VERSION
MSBUILD_JNI_LIBS_SRC_DIR
MSBUILD_ANDROID_OUTPUT_APK_NAME
MSBUILD_ANDROID_GRADLE_BUILD_OUTPUT_DIR
如要設定及執行範例,請執行以下操作:
- 在 Visual Studio 中,開啟並建構 HelloJNI 範例。
- 新增 Android arm64-v8a 平台。詳情請參閱新增 Android 平台。
- 在新平台新增 Android APK 項目。
- 編譯專案。
- 新增下列 Android 平台,然後為每個 Android 平台新增 Android APK 項目:Android-armeabi-v7a、Android-x86 和 Android-x86_64。
- 建構並執行範例。
Endless-Tunnel
Endless-Tunnel 範例是一款 Android 遊戲,玩家要努力抵達隧道盡頭,同時收集白色方塊。這個範例是從 GitHub 上的 Android NDK 存放區中的 OpenGL 範例移植而來,且並未提供 Windows 版本的遊戲。
這個範例已完成相關設定和 Android 平台設定,因此您可以在 Visual Studio 中建構並執行專案,無須進行任何修改。開啟解決方案時,Solution Explorer 會顯示下列模組:
- endless-tunnel:顯示遊戲邏輯的應用程式模組。
- glm:以靜態資料庫形式建構的 OpenGL Math 存放區快照。
- native_app_glue:用來與 NativeActivity 物件通訊的 NDK 包裝函式。
Teapot
Teapot 範例顯示使用 OpenGL ES 轉譯並已移植到 Android Game Development Extension 的經典茶壺,用於展示下列功能:
- 跨平台專案開發:您可以為 Windows 和 Android 建構 Teapot 範例。
- 使用自訂 Android 包裝:Gradle 建構指令碼已移至範例的根目錄,即
Teapot.sln
檔案的所在位置。 - 自訂 Android 設定,示範如何使用 Address Sanitizer (ASan) 和 Hardware Address Sanitizer (HWASan)。
Teapot 範例的導入可分為多個部分,對於大型跨平台應用程式和遊戲來說很常見:
GameApplication
模組:定義使用者動作和應用程式狀態,例如使用者旋轉茶壺或更新應用程式統計資料。GameEngine
模組:導入核心轉譯模組。
如要設定範例並在 Android 上執行,請參閱快速入門導覽課程。如要設定範例並在 Windows 上執行:
- 安裝 GLEW:
- 下載並解壓縮 GLEW。
- 將二進位檔案從
$your-glew-directory\bin\Release\x64
複製到%SystemRoot%\system32
。
- 安裝 freeglut:
- 下載並解壓縮 freeglut。
- 將
$your-freeglut-directory\bin\x86\freeglut.dll
複製到%SystemRoot%\system32
。
- 新增 freeglut 專案依附元件:
- 在 Visual Studio 中開啟
Teapot.sln
。 - 在選單中,依序點選「Debug」>「x64」>「Local Windows Debugger」。
- 在「Solution Explorer」中的「GameApplication」上按一下滑鼠右鍵,依序選擇「Properties」>「C/C++」>「General」>「Additional Include Directories」。
- 將
$your-freeglut-dir\include
加入路徑中。
- 按一下「OK」。
- 依序選擇「Linker」>「General」>「Additional Library Directories」。
- 將
$your-freeglut-dir\lib\x64
加入路徑中。 - 按一下「OK」。
- 依序選擇「Linker」>「General」>「Additional Library Directories」。
- 將
freeglut.lib
加入路徑中。 - 按一下「OK」。
- 在 Visual Studio 中開啟
- 新增 GLEW 專案依附元件:
- 在「Solution Explorer」窗格中的「GameApplication」上按一下滑鼠右鍵,依序選擇「Properties」>「C/C++」>「General」>「Additional Include Directories」。
- 將
$your-glew-dir\include
加入路徑中。 - 按一下「OK」。
- 依序選擇「Linker」>「General」>「Additional Library Directories」。
- 將
$your-glew-dir\lib\Release\x86
加入路徑中。 - 按一下「OK」。
- 依序選擇「Linker」>「General」>「Additional Library Directories」。
- 將
glew32.lib
加入路徑中。 - 按一下「OK」。
- 在 Windows 上執行範例:
- 在 Visual Studio 工具列中,按一下「Local Windows Debugger」執行按鈕。
- 範例應如下所示:
AssemblyCode-Link-Objects
這是範本專案,示範如何從組合原始碼和 C/C++ 原始碼產生 Android 原生資料庫。主要元件如下:
AssemblyCode-Link-Objects
:使用 C++ 和組合原始碼建構的主要 Android 原生資料庫。StaticLib
:匯出from_static_lib_assembly_code_as
函式的輔助靜態資料庫。
這個專案支援多個架構。每個支援的架構都有自己的來源檔案,可導入從 StaticLib
匯出的函式。對於正在建構的平台,只應納入組合來源檔案。這個專案使用自訂建構工具在建構作業中納入組合檔案。
如要設定及建構範例,請執行以下操作:
- 在 Visual Studio 中,確認是否已為組合檔案設定自訂建構工具:
- 前往「Solution Explorer」,在組合檔案上按一下滑鼠右鍵,然後點選「Properties」。系統隨即會開啟檔案的「Properties Pages」對話方塊。
- 選取設定和平台,例如為「Android-arm64-v8a」選擇「All configurations」。
- 依序前往「General」>「Exclude from Build」,確認已設定為「No」。
- 依序前往確認「General」>「Item Type」,確認已設為「Custom Build Tool」。
- 如要套用變更,按一下「Apply」。
- 依序前往「Configuration Properties」>「Custom Build Tools」>「Command Line」,確認已設為
$(AsToolExe) -o "$(IntDir)%(FileName).o" %(FullPath)
。NDK 會為每個 CPU 架構納入個別組合器,且$(AsToolExe)
會對應到正確的組合器。這個範例使用 NDK 工具鍊同時建構 x86 和 x86_64 Android 專案。如要在 x86_64 Android 平台中使用 yasm,請改用$(YasmToolExe)
。 - 依序前往「Configuration Properties」>「Custom Build Tools」>「Outputs」,確認已設為
$(IntDir)%(FileName).o
。這個字串必須加入「Command Line」設定中。 - 依序前往「Configuration Properties」>「Custom Build Tools」>「Link Objects」,確認已設為
Yes
。
舉例來說,「Android-arm64-v8a」的設定應如以下螢幕截圖所示:
- 建構專案。這項操作會建構
libAssmeblyCodeLinkObjects.so
檔案:- 開啟
AssemblyCode-Link-Objects.sln
檔案。 - 在選單中,依序點選「Build」>「Build Solution」。
- 開啟
- 如要確認函式是否已正確匯出至 Android 程式庫,請使用 nm.exe NDK 工具:
- 在指令列中,前往範例目錄。
- 前往由建構作業產生的 Android 程式庫位置。預設位置與 arm64-v8a 平台的
$sample_dir\$solution_configuration\$solution_platform\$platform
和$sample_dir\Debug\Android-arm64-v8a\arm64-v8a
類似。 - 執行下列指令,以驗證匯出的符號部分是否包含函式:
…\ndk\toolschains\llvm\prebuilt\windows-x86_64\aarch64-linux-android\bin\nm.exe --defined-only …\Debug\Android-arm64-v8a\arm64-v8a\libAssmeblyCodeLinkObjects.so
輸出結果應會包含以下符號清單:
T from_shared_object_assembly_code_as
T from_static_lib_assembly_code_as
PoolAllocator
PoolAllocator 範例是 Android 應用程式,其中包含以集區為基礎的記憶體配置器,可非常有效率地提供固定大小的區塊。
配置器會在初始化時使用 mmap
預先配置整個記憶體。系統會使用連結清單追蹤空白區塊。接著,記憶體配置是快速的 O(1)
作業,可傳回連結清單的頭,而釋放作業也是 O(1)
作業,因為它會將區塊新增至連結清單的後方。
本範例提供兩種使用 HWASan 的解決方案設定。
HWASan
:這項設定示範如何以最簡單的方式,搭配自訂記憶體配置器使用 HWASan。記憶體配置器的內部實作項目會改用malloc
/free
呼叫,這些呼叫會由 HWASan 自動追蹤。雖然記憶體配置器不再以池為基礎的配置器運作,但 HWASan 仍可協助您找出重要的記憶體錯誤,例如釋放後使用。HWASan-Advanced
:這個設定說明如何將 HWASan 完全整合至自訂記憶體配置器,而不會變更配置器使用的原始配置機制。它會使用 HWASan 標記方法,為預先配置集區中的記憶體區塊加上標記,將區塊大小四捨五入至 HWASan 所需的區塊大小下限,並在區塊傳回集區時重設標記。
請使用 HWASan
設定,因為它更簡單,而且可以協助您找出常見的記憶體錯誤。如要瞭解 HWASan 的運作方式,或在使用 HWASan 時保留記憶體配置器的內部語意,請探索 HWASan-Advanced
設定的實作方式。