Von NativeActivity migrieren Teil des Android Game Development Kit.
Auf dieser Seite wird beschrieben, wie Sie von
NativeActivity
bis
GameActivity
in deinem Android-Spielprojekt.
GameActivity
basiert auf NativeActivity
von Android
mit Verbesserungen und neuen Funktionen:
- Unterstützt
Fragment
von Jetpack. - Unterstützt
TextInput
für eine einfachere Integration über die Softtastatur. - Verarbeitet Tipp- und Schlüsselereignisse in der Java-Klasse
GameActivity
, stattNativeActivity
onInputEvent
-Schnittstelle.
Vor der Migration sollten Sie die
Startleitfaden, in dem beschrieben wird, wie Sie
um GameActivity
einzurichten und in Ihr Projekt zu integrieren.
Aktualisierung des Java-Build-Skripts
GameActivity
wird verteilt als
Jetpack-Bibliothek. Wenden Sie die beschriebenen Schritte zur Aktualisierung des Gradle-Skripts an.
im Startleitfaden:
Aktivieren Sie die Jetpack-Bibliothek in der Datei
gradle.properties
Ihres Projekts:android.useAndroidX=true
Optional können Sie in derselben
gradle.properties
-Datei eine Prefab-Version angeben. Beispiel:android.prefabVersion=2.0.0
So aktivieren Sie die Prefab-Funktion in der
build.gradle
-Datei Ihrer App:android { ... // other configurations buildFeatures.prefab true }
Fügen Sie Ihrer Anwendung die Abhängigkeit
GameActivity
hinzu:- Fügen Sie die Bibliotheken
core
undgames-activity
hinzu. - Wenn dein aktuell unterstütztes Mindest-API-Level weniger als 16 beträgt, aktualisiere es auf mindestens 16.
- Aktualisiere die kompilierte SDK-Version auf die Version, die der
games-activity
Bibliothek erforderlich ist. Jetpack erfordert normalerweise die neueste SDK-Version unter die Build-Erstellungszeit des Release.
Die aktualisierte Datei
build.gradle
könnte in etwa so aussehen:android { compiledSdkVersion 33 ... // other configurations. defaultConfig { minSdkVersion 16 } ... // other configurations. buildFeatures.prefab true } dependencies { implementation 'androidx.core:core:1.9.0' implementation 'androidx.games:games-activity:1.2.2' }
- Fügen Sie die Bibliotheken
Kotlin- oder Java-Codeaktualisierungen
NativeActivity
kann als Startaktivität verwendet werden und erstellt einen Vollbildmodus
. Derzeit kann GameActivity nicht als Startvorgang verwendet werden
Aktivitäten. Apps müssen eine Klasse von GameActivity
ableiten und diese als
der Startaktivität. Sie müssen außerdem weitere Konfigurationsänderungen vornehmen,
eine Vollbild-App zu erstellen.
Bei den folgenden Schritten wird davon ausgegangen, dass Ihre Anwendung NativeActivity
als Startvorgang verwendet
Aktivitäten. Ist dies nicht der Fall, können Sie die meisten dieser Vorschläge überspringen.
Erstellen Sie eine Kotlin- oder Java-Datei, um die neue Startaktivität zu hosten. Beispiel: Mit dem folgenden Code werden die
MainActivity
als Startaktivität und lädt die native Hauptbibliothek der Anwendung,libAndroidGame.so
:Kotlin
class MainActivity : GameActivity() { override fun onResume() { super.onResume() // Use the function recommended from the following page: // https://d.android.com/training/system-ui/immersive hideSystemBars() } companion object { init { System.loadLibrary("AndroidGame") } } }
Java
public class MainActivity extends GameActivity { protected void onResume() { super.onResume(); // Use the function recommended from // https://d.android.com/training/system-ui/immersive hideSystemBars(); } static { System.loadLibrary("AndroidGame"); } }
Erstellen Sie in der Datei
res\values\themes.xml
ein Vollbild-App-Design:<resources xmlns:tools="http://schemas.android.com/tools"> <!-- Base application theme. --> <style name="Application.Fullscreen" parent="Theme.AppCompat.Light.NoActionBar"> <item name="android:windowFullscreen">true</item> <item name="android:windowContentOverlay">@null</item>" </style> </resources>
Wenden Sie das Design auf die Anwendung in der Datei
AndroidManifest.xml
an:<application android:theme=”@style/Application.Fullscreen”> <!-- other configurations not listed here. --> </application>
Eine ausführliche Anleitung für den Vollbildmodus finden Sie unter ausführlichen Leitfaden und eine Beispielimplementierung in Games-Beispiel-Repository.
Der Name der nativen Bibliothek wird in dieser Migrationsanleitung nicht geändert. Wenn Sie die Namen der nativen Bibliothek in den folgenden drei Standorte:
Kotlin- oder Java-Code:
System.loadLibrary(“AndroidGame”)
AndroidManifest.xml
:<meta-data android:name="android.app.lib_name" android:value="AndroidGame" />
Geben Sie in der C/C++-Build-Skriptdatei, z. B.
CMakeLists.txt
, Folgendes ein:add_library(AndroidGame ...)
Aktualisierungen des C/C++ Build-Scripts
In der Anleitung in diesem Abschnitt wird cmake
als Beispiel verwendet. Wenn Ihre Anwendung
ndk-build
verwendet, müssen Sie sie den entsprechenden Befehlen zuordnen, die in
Dokumentationsseite zu ndk-build.
Die C/C++-Implementierung von GameActivity lieferte einen Quellcode-Release. Für Version 1.2.2 oder höher wird ein statischer Bibliotheksrelease bereitgestellt. Die statische ist der empfohlene Veröffentlichungstyp.
Die Veröffentlichung ist im AAE enthalten
prefab
Dienstprogramm. Der native Code enthält die C/C++-Quellen von GameActivity und den
native_app_glue
-Code. Sie müssen gemeinsam mit Ihren
C/C++ Code der Anwendung.
NativeActivity
-Anwendungen verwenden bereits den native_app_glue
Code innerhalb des NDK versendet. Du musst sie durch die Version von GameActivity ersetzen
von native_app_glue
. Davon abgesehen sind alle cmake
darin dokumentierten Schritte
finden Sie im Startleitfaden:
Importieren Sie entweder die statische C/C++-Bibliothek oder den C/++-Quellcode in Ihr wie im Folgenden beschrieben.
Static-Bibliothek
Importieren Sie das statische
game-activity
-Objekt in die DateiCMakeLists.txt
Ihres Projekts. in dasgame-activity_static
-Fertigmodul:find_package(game-activity REQUIRED CONFIG) target_link_libraries(${PROJECT_NAME} PUBLIC log android game-activity::game-activity_static)
Quellcode
Importieren Sie den
game-activity
in die DateiCMakeLists.txt
Ihres Projekts. Paket und fügen es Ihrem Ziel hinzu. Dasgame-activity
-Paket benötigtlibandroid.so
. Fehlt sie, müssen Sie sie auch importieren.find_package(game-activity REQUIRED CONFIG) ... target_link_libraries(... android game-activity::game-activity)
Entfernen Sie alle Verweise auf den
native_app_glue
-Code von NDK, z. B.:${ANDROID_NDK}/sources/android/native_app_glue/android_native_app_glue.c ... set(CMAKE_SHARED_LINKER_FLAGS "${CMAKE_SHARED_LINKER_FLAGS} -u ANativeActivity_onCreate")
Wenn Sie den Quellcode-Release verwenden, geben Sie den
GameActivity
-Quellcode an Dateien. Andernfalls können Sie diesen Schritt überspringen.get_target_property(game-activity-include game-activity::game-activity INTERFACE_INCLUDE_DIRECTORIES) add_library(${PROJECT_NAME} SHARED main.cpp ${game-activity-include}/game-activity/native_app_glue/android_native_app_glue.c ${game-activity-include}/game-activity/GameActivity.cpp ${game-activity-include}/game-text-input/gametextinput.cpp)
Umgehen des Problems „UnexpectedLinkError“
Wenn ein UnsatsifiedLinkError
für die
com.google.androidgamesdk.GameActivity.initializeNativeCode()
-Funktion, hinzufügen
diesen Code in Ihre CMakeLists.txt
-Datei ein:
set(CMAKE_SHARED_LINKER_FLAGS
"${CMAKE_SHARED_LINKER_FLAGS} -u \
Java_com_google_androidgamesdk_GameActivity_initializeNativeCode")
Aktualisierungen des C/C++-Quellcodes
Mit den folgenden Schritten kannst du NativeActivity
-Referenzen in deinem
Anwendung mit GameActivity
:
Verwende die
native_app_glue
, die mitGameActivity
veröffentlicht wurde. Suchen und Ersetzen Sie die gesamteandroid_native_app_glue.h
-Nutzung durch:#include <game-activity/native_app_glue/android_native_app_glue.h>
Setze sowohl den Bewegungsereignisfilter als auch den Schlüsselereignisfilter auf
NULL
, damit deine App Eingangsereignisse von allen Eingabegeräten empfangen. Das machst du normalerweise drinnenandroid_main()
-Funktion:void android_main(android_app* app) { ... // other init code. android_app_set_key_event_filter(app, NULL); android_app_set_motion_event_filter(app, NULL); ... // additional init code, and game loop code. }
AInputEvent
-bezogenen Code entfernen und durch GameActivity-Code ersetzenInputBuffer
-Implementierung:while (true) { // Read all pending events. int events; struct android_poll_source* source; // If not animating, block forever waiting for events. // If animating, loop until all events are read, then continue // to draw the next frame of animation. while ((ALooper_pollAll(engine.animating ? 0 : -1, nullptr, &events, (void**)&source)) >= 0) { // Process this app cycle or inset change event. if (source) { source->process(source->app, source); } ... // Other processing. // Check if app is exiting. if (state->destroyRequested) { engine_term_display(&engine); return; } } // Process input events if there are any. engine_handle_input(state); if (engine.animating) { // Draw a game frame. } } // Implement input event handling function. static int32_t engine_handle_input(struct android_app* app) { auto* engine = (struct engine*)app->userData; auto ib = android_app_swap_input_buffers(app); if (ib && ib->motionEventsCount) { for (int i = 0; i < ib->motionEventsCount; i++) { auto *event = &ib->motionEvents[i]; int32_t ptrIdx = 0; switch (event->action & AMOTION_EVENT_ACTION_MASK) { case AMOTION_EVENT_ACTION_POINTER_DOWN: case AMOTION_EVENT_ACTION_POINTER_UP: // Retrieve the index for the starting and the ending of any secondary pointers ptrIdx = (event->action & AMOTION_EVENT_ACTION_POINTER_INDEX_MASK) >> AMOTION_EVENT_ACTION_POINTER_INDEX_SHIFT; case AMOTION_EVENT_ACTION_DOWN: case AMOTION_EVENT_ACTION_UP: engine->state.x = GameActivityPointerAxes_getAxisValue( &event->pointers[ptrIdx], AMOTION_EVENT_AXIS_X); engine->state.y = GameActivityPointerAxes_getAxisValue( &event->pointers[ptrIdx], AMOTION_EVENT_AXIS_Y); break; case AMOTION_EVENT_ACTION_MOVE: // Process the move action: the new coordinates for all active touch pointers // are inside the event->pointers[]. Compare with our internally saved // coordinates to find out which pointers are actually moved. Note that there is // no index embedded inside event->action for AMOTION_EVENT_ACTION_MOVE (there // might be multiple pointers moved at the same time). ... break; } } android_app_clear_motion_events(ib); } // Process the KeyEvent in a similar way. ... return 0; }
Logik für NativeActivity prüfen und aktualisieren
AInputEvent
Wie im vorherigen Schritt gezeigt, hat „InputBuffer
“ von GameActivity die Verarbeitung außerhalb derALooper_pollAll()
-Schleife erfolgt.Nutzung von
android_app::activity->clazz
ersetzen durchandroid_app:: activity->javaGameActivity
. In „GameActivity“ wird die JavaGameActivity
-Instanz
Weitere Schritte
In den vorherigen Schritten wurde die Funktionalität von NativeActivity beschrieben. GameActivity
hat jedoch
weitere Funktionen, die Sie möglicherweise verwenden möchten:
- TextInput enthalten.
- Controller.
- Fragment:
- Neues Fenster, in NativeAppGlueAppCmd definierte InSets-Befehle
Wir empfehlen Ihnen, diese Funktionen auszuprobieren und für Ihr Unternehmen Spiele.
Wenn du Fragen oder Empfehlungen zu GameActivity oder anderen AGDK hast erstellen Sie einen Fehler, um uns zu informieren.