Esegui la migrazione da NativeActivity Parte del Android Game Development Kit.
In questa pagina viene descritto come eseguire la migrazione da
Da NativeActivity
a
GameActivity
nel tuo progetto di gioco Android.
GameActivity
si basa su NativeActivity
su Android
, con miglioramenti e nuove funzionalità:
- Supporta
Fragment
di Jetpack. - Aggiunge il supporto
TextInput
per facilitare l'integrazione della tastiera su schermo. - Gestisce gli eventi touch e chiave nella classe Java
GameActivity
anziché l'interfacciaNativeActivity
onInputEvent
.
Prima di eseguire la migrazione, ti consigliamo di leggere
Guida introduttiva, che descrive come
per configurare e integrare GameActivity
nel tuo progetto.
Aggiornamenti dello script di build Java
GameActivity
è distribuito come
Libreria Jetpack Assicurati di applicare i passaggi di aggiornamento dello script Gradle descritti
Nella Guida introduttiva:
Abilita la libreria Jetpack nel file
gradle.properties
del tuo progetto:android.useAndroidX=true
(Facoltativo) Specifica una versione prefab, nello stesso file
gradle.properties
, Ad esempio:android.prefabVersion=2.0.0
Attiva la funzionalità Prefabbricata nel file
build.gradle
dell'app:android { ... // other configurations buildFeatures.prefab true }
Aggiungi la dipendenza
GameActivity
alla tua applicazione:- Aggiungi le librerie
core
egames-activity
. - Se il tuo attuale livello API supportato è inferiore a 16, aggiornalo almeno 16.
- Aggiorna la versione compilata dell'SDK con quella
games-activity
libreria richiede. Jetpack richiede in genere l'ultima versione dell'SDK all'indirizzo la data e l'ora di build della release.
Il file
build.gradle
aggiornato potrebbe avere il seguente aspetto: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' }
- Aggiungi le librerie
Aggiornamenti del codice Kotlin o Java
NativeActivity
può essere utilizzato come attività di avvio e crea uno schermo intero
un'applicazione. Al momento GameActivity non può essere utilizzato come avvio
attività. Le app devono derivare una classe da GameActivity
e utilizzarla come
l'attività di avvio. Devi inoltre apportare ulteriori modifiche alla configurazione
creare un'app a schermo intero.
I passaggi seguenti presuppongono che la tua applicazione utilizzi NativeActivity
come avvio
attività. In caso contrario, puoi saltare la maggior parte di questi passaggi.
Crea un file Kotlin o Java per ospitare la nuova attività di avvio. Ad esempio: il codice seguente crea
MainActivity
come attività di avvio e carica la libreria nativa principale dell'applicazione,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"); } }
Crea un tema dell'app a schermo intero nel file
res\values\themes.xml
:<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>
Applica il tema all'applicazione nel file
AndroidManifest.xml
:<application android:theme=”@style/Application.Fullscreen”> <!-- other configurations not listed here. --> </application>
Per istruzioni dettagliate sulla modalità a schermo intero, consulta una guida immersiva e esempi di implementazione in il repository Games-samples.
Questa guida alla migrazione non modifica il nome della libreria nativa. Se cambi assicurati che i nomi delle librerie native siano coerenti nelle località:
Codice Kotlin o Java:
System.loadLibrary(“AndroidGame”)
AndroidManifest.xml
:<meta-data android:name="android.app.lib_name" android:value="AndroidGame" />
All'interno del file di script di build C/C++, ad esempio
CMakeLists.txt
:add_library(AndroidGame ...)
Aggiornamenti degli script di build C/C++
Le istruzioni in questa sezione utilizzano cmake
come esempio. Se la tua applicazione
usi ndk-build
, devi mapparli ai comandi equivalenti descritti in
pagina della documentazione di ndk-build.
L'implementazione C/C++ di GameActivity fornisce una release del codice sorgente. Per la versione 1.2.2 e successive, viene fornita una release della libreria statica. Il feed statico libreria è il tipo di release consigliato.
La release è pacchettizzata all'interno dell'AAR con
prefab
utilità. Il codice nativo include le sorgenti C/C++ di GameActivity e
Codice di native_app_glue
. Devono essere creati insieme
C/C++ dell'applicazione.
NativeActivity
applicazioni usano già native_app_glue
fornito all'interno dell'NDK. Devi sostituirla con la versione di GameActivity
di native_app_glue
. A parte questo, tutti i cmake
passaggi sono documentati
consulta la guida introduttiva:
Importa la libreria statica C/C++ o il codice sorgente C/++ nel tuo progetto come segue.
Libreria statica
Nel file
CMakeLists.txt
del progetto, importa l'elemento staticogame-activity
nel modulo prefabbricatogame-activity_static
:find_package(game-activity REQUIRED CONFIG) target_link_libraries(${PROJECT_NAME} PUBLIC log android game-activity::game-activity_static)
Codice sorgente
Nel file
CMakeLists.txt
del progetto, importagame-activity
e aggiungilo al target. Il pacchettogame-activity
richiedelibandroid.so
, quindi se manca, devi importarlo.find_package(game-activity REQUIRED CONFIG) ... target_link_libraries(... android game-activity::game-activity)
Rimuovi tutti i riferimenti al codice
native_app_glue
dell'NDK, ad esempio:${ANDROID_NDK}/sources/android/native_app_glue/android_native_app_glue.c ... set(CMAKE_SHARED_LINKER_FLAGS "${CMAKE_SHARED_LINKER_FLAGS} -u ANativeActivity_onCreate")
Se utilizzi la release del codice sorgente, includi il codice sorgente
GameActivity
. In caso contrario, salta questo passaggio.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)
Agire sul problema UnauthorizedLinkError
Se riscontri un UnsatsifiedLinkError
per
Funzione com.google.androidgamesdk.GameActivity.initializeNativeCode()
, aggiungi
questo codice al tuo file CMakeLists.txt
:
set(CMAKE_SHARED_LINKER_FLAGS
"${CMAKE_SHARED_LINKER_FLAGS} -u \
Java_com_google_androidgamesdk_GameActivity_initializeNativeCode")
Aggiornamenti del codice sorgente C/C++
Segui questi passaggi per sostituire NativeActivity
riferimenti nel tuo
applicazione con GameActivity
:
Utilizza
native_app_glue
rilasciato conGameActivity
. Ricerca e sostituisci tutti i valori di utilizzo diandroid_native_app_glue.h
con:#include <game-activity/native_app_glue/android_native_app_glue.h>
Imposta il filtro degli eventi di movimento e degli eventi chiave su
NULL
in modo che la tua app possa ricevono eventi di input da tutti i dispositivi di input. Solitamente lo fai all'interno Funzioneandroid_main()
: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. }
Rimuovi il codice correlato di
AInputEvent
e sostituiscilo con GameActivity Implementazione diInputBuffer
: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; }
Rivedi e aggiorna la logica associata a NativeActivity
AInputEvent
. Come mostrato nel passaggio precedente, l'attivitàInputBuffer
di GameActivity l'elaborazione è esterna al loopALooper_pollAll()
.Sostituisci l'utilizzo di
android_app::activity->clazz
conandroid_app:: activity->javaGameActivity
. GameActivity rinomina Istanza JavaGameActivity
.
Passaggi aggiuntivi
I passaggi precedenti trattano la funzionalità di NativeActivity, ma GameActivity
ha
altre funzionalità che potresti voler utilizzare:
- TextInput.
- Controller di gioco.
- Frammento.
- Nuova finestra InSets i comandi definiti in NativeAppGlueAppCmd.
Ti consigliamo di esplorare queste funzionalità e di adottarle in modo appropriato per il tuo giochi.
Se hai domande o consigli relativi ad Attività di gioco o ad altri AGDK librerie, crea un bug per comunicarcelo.