範例

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

如要設定及執行範例,請執行以下操作:

  1. 在 Visual Studio 中,開啟並建構 HelloJNI 範例。
  2. 新增 Android arm64-v8a 平台。詳情請參閱新增 Android 平台
  3. 在新平台新增 Android APK 項目
  4. 編譯專案。
  5. 新增下列 Android 平台,然後為每個 Android 平台新增 Android APK 項目:Android-armeabi-v7aAndroid-x86Android-x86_64
  6. 建構並執行範例。

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 上執行:

  1. 安裝 GLEW:
    1. 下載並解壓縮 GLEW
    2. 將二進位檔案從 $your-glew-directory\bin\Release\x64 複製到 %SystemRoot%\system32
  2. 安裝 freeglut:
    1. 下載並解壓縮 freeglut
    2. $your-freeglut-directory\bin\x86\freeglut.dll 複製到 %SystemRoot%\system32
  3. 新增 freeglut 專案依附元件:
    1. 在 Visual Studio 中開啟 Teapot.sln
    2. 在選單中,依序點選「Debug」>「x64」>「Local Windows Debugger」
    3. 在「Solution Explorer」中的「GameApplication」上按一下滑鼠右鍵,依序選擇「Properties」>「C/C++」>「General」>「Additional Include Directories」
    4. $your-freeglut-dir\include 加入路徑中。
      「Additional Include Directories」對話方塊的螢幕截圖。
    5. 按一下「OK」。
    6. 依序選擇「Linker」>「General」>「Additional Library Directories」
    7. $your-freeglut-dir\lib\x64 加入路徑中。「Additional Library Directories」對話方塊的螢幕截圖。
    8. 按一下「OK」。
    9. 依序選擇「Linker」>「General」>「Additional Library Directories」
    10. freeglut.lib 加入路徑中。
    11. 按一下「OK」。
  4. 新增 GLEW 專案依附元件:
    1. 在「Solution Explorer」窗格中的「GameApplication」上按一下滑鼠右鍵,依序選擇「Properties」>「C/C++」>「General」>「Additional Include Directories」
    2. $your-glew-dir\include 加入路徑中。
    3. 按一下「OK」。
    4. 依序選擇「Linker」>「General」>「Additional Library Directories」
    5. $your-glew-dir\lib\Release\x86 加入路徑中。
    6. 按一下「OK」。
    7. 依序選擇「Linker」>「General」>「Additional Library Directories」
    8. glew32.lib 加入路徑中。
    9. 按一下「OK」。
  5. 在 Windows 上執行範例:
    1. 在 Visual Studio 工具列中,按一下「Local Windows Debugger」執行按鈕。
    2. 範例應如下所示:
      在 Windows 上執行的 Teapot 範例螢幕截圖。

這是範本專案,示範如何從組合原始碼和 C/C++ 原始碼產生 Android 原生資料庫。主要元件如下:

  • AssemblyCode-Link-Objects:使用 C++ 和組合原始碼建構的主要 Android 原生資料庫。
  • StaticLib:匯出 from_static_lib_assembly_code_as 函式的輔助靜態資料庫。

這個專案支援多個架構。每個支援的架構都有自己的來源檔案,可導入從 StaticLib 匯出的函式。對於正在建構的平台,只應納入組合來源檔案。這個專案使用自訂建構工具在建構作業中納入組合檔案。

如要設定及建構範例,請執行以下操作:

  1. 在 Visual Studio 中,確認是否已為組合檔案設定自訂建構工具:
    1. 前往「Solution Explorer」,在組合檔案上按一下滑鼠右鍵,然後點選「Properties」。系統隨即會開啟檔案的「Properties Pages」對話方塊。
    2. 選取設定和平台,例如為「Android-arm64-v8a」選擇「All configurations」
    3. 依序前往「General」>「Exclude from Build」,確認已設定為「No」
    4. 依序前往確認「General」>「Item Type」,確認已設為「Custom Build Tool」
    5. 如要套用變更,按一下「Apply」
    6. 依序前往「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)
    7. 依序前往「Configuration Properties」>「Custom Build Tools」>「Outputs」,確認已設為 $(IntDir)%(FileName).o這個字串必須加入「Command Line」設定中。
    8. 依序前往「Configuration Properties」>「Custom Build Tools」>「Link Objects」,確認已設為 Yes

    舉例來說,「Android-arm64-v8a」的設定應如以下螢幕截圖所示:

    「Property Page」上的「Custom Build Tools」螢幕截圖。
  2. 建構專案。這項操作會建構 libAssmeblyCodeLinkObjects.so 檔案:
    1. 開啟 AssemblyCode-Link-Objects.sln 檔案。
    2. 在選單中,依序點選「Build」>「Build Solution」
  3. 如要確認函式是否已正確匯出至 Android 程式庫,請使用 nm.exe NDK 工具:
    1. 在指令列中,前往範例目錄。
    2. 前往由建構作業產生的 Android 程式庫位置。預設位置與 arm64-v8a 平台的 $sample_dir\$solution_configuration\$solution_platform\$platform$sample_dir\Debug\Android-arm64-v8a\arm64-v8a 類似。
    3. 執行下列指令,以驗證匯出的符號部分是否包含函式:
        \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 設定的實作方式。