NativeActivity'den taşıma Android Game Development Kit'in bir parçasıdır.
Bu sayfada, Android oyun projenizde NativeActivity'den GameActivity'e nasıl geçiş yapacağınız açıklanmaktadır.
GameActivity, Android çerçevesindeki NativeActivity'ye dayanır ve geliştirmeler ile yeni özellikler içerir:
- Jetpack'ten
Fragmentdesteklenir. - Yumuşak klavye entegrasyonunu kolaylaştırmak için
TextInputdesteği ekler. NativeActivityonInputEventarayüzü yerineGameActivityJava sınıfındaki dokunma ve tuş etkinliklerini işler.
Taşıma işleminden önce, projenizde GameActivity'ı nasıl ayarlayıp entegre edeceğinizi açıklayan başlangıç kılavuzunu okumanızı öneririz.
Java derleme komut dosyası güncellemeleri
GameActivity, Jetpack kitaplığı olarak dağıtılır. Başlangıç kılavuzunda açıklanan Gradle komut dosyası güncelleme adımlarını uyguladığınızdan emin olun:
Projenizin
gradle.propertiesdosyasında Jetpack kitaplığını etkinleştirin:android.useAndroidX=trueİsteğe bağlı olarak, aynı
gradle.propertiesdosyasında bir Prefab sürümü belirtin. Örneğin:android.prefabVersion=2.0.0Uygulamanızın
build.gradledosyasında Prefab özelliğini etkinleştirin:android { ... // other configurations buildFeatures.prefab true }Uygulamanıza
GameActivitybağımlılığını ekleyin:corevegames-activitykitaplıklarını ekleyin.- Mevcut desteklenen minimum API seviyeniz 16'dan düşükse bunu en az 16 olacak şekilde güncelleyin.
- Derlenmiş SDK sürümünü,
games-activitykitaplığının gerektirdiği sürüme güncelleyin. Jetpack genellikle yayın derleme zamanında en yeni SDK sürümünü gerektirir.
Güncellenen
build.gradledosyanız şöyle görünebilir: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' }
Kotlin veya Java kodu güncellemeleri
NativeActivity, başlangıç etkinliği olarak kullanılabilir ve tam ekran bir uygulama oluşturur. Şu anda GameActivity, başlangıç etkinliği olarak kullanılamaz. Uygulamalar, GameActivity öğesinden bir sınıf türetmeli ve bunu başlangıç etkinliği olarak kullanmalıdır. Tam ekran uygulama oluşturmak için ek yapılandırma değişiklikleri de yapmanız gerekir.
Aşağıdaki adımlarda, uygulamanızın başlangıç etkinliği olarak NativeActivity kullandığı varsayılmaktadır. Bu durum geçerli değilse çoğu adımı atlayabilirsiniz.
Yeni başlangıç etkinliğine ev sahipliği yapacak bir Kotlin veya Java dosyası oluşturun. Örneğin, aşağıdaki kod, başlatma etkinliği olarak
MainActivityöğesini oluşturur ve uygulamanın ana yerel kitaplığı olanlibAndroidGame.soöğesini yükler: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"); } }
res\values\themes.xmldosyasında tam ekran uygulama teması oluşturun:<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>Temayı
AndroidManifest.xmldosyasındaki uygulamaya uygulayın:<application android:theme=”@style/Application.Fullscreen”> <!-- other configurations not listed here. --> </application>Tam ekran moduyla ilgili ayrıntılı talimatlar için kapsamlı kılavuzu ve games-samples deposundaki örnek uygulamayı inceleyin.
Bu taşıma kılavuzu, yerel kitaplık adını değiştirmez. Değiştirirseniz yerel kitaplık adlarının aşağıdaki üç konumda tutarlı olduğundan emin olun:
Kotlin veya Java kodu:
System.loadLibrary(“AndroidGame”)AndroidManifest.xml:<meta-data android:name="android.app.lib_name" android:value="AndroidGame" />C/C++ derleme komut dosyası içinde (ör.
CMakeLists.txt):add_library(AndroidGame ...)
C/C++ derleme komut dosyası güncellemeleri
Bu bölümdeki talimatlarda örnek olarak cmake kullanılmaktadır. Uygulamanızda ndk-build kullanılıyorsa bunları ndk-build dokümanları sayfasında açıklanan eşdeğer komutlarla eşlemeniz gerekir.
GameActivity'nin C/C++ uygulaması, kaynak kodu sürümü sunmaktadır. 1.2.2 ve sonraki sürümler için statik kitaplık sürümü sağlanır. Statik kitaplık, önerilen sürüm türüdür.
Sürüm, prefab yardımcı programı ile AAR'nin içine yerleştirilir. Yerel kod, GameActivity'nin C/C++ kaynaklarını ve native_app_glue kodunu içerir. Uygulamanızın C/C++ koduyla birlikte oluşturulmaları gerekir.
NativeActivity uygulama, NDK'da gönderilen native_app_glue kodunu zaten kullanıyor. Bunu GameActivity'nin native_app_glue sürümüyle değiştirmeniz gerekir. Bunun dışında, başlangıç kılavuzunda belgelenen tüm cmake adımlar geçerlidir:
C/C++ statik kitaplığını veya C/++ kaynak kodunu projenize aşağıdaki şekilde aktarın.
Statik kitaplık
Projenizin
CMakeLists.txtdosyasında,game-activitystatik kitaplığınıgame-activity_staticprefab modülüne aktarın:find_package(game-activity REQUIRED CONFIG) target_link_libraries(${PROJECT_NAME} PUBLIC log android game-activity::game-activity_static)Kaynak kodu
Projenizin
CMakeLists.txtdosyasındagame-activitypaketini içe aktarın ve hedefinize ekleyin.game-activitypaketilibandroid.sogerektirir. Bu nedenle, eksikse onu da içe aktarmanız gerekir.find_package(game-activity REQUIRED CONFIG) ... target_link_libraries(... android game-activity::game-activity)NDK'nın
native_app_gluekoduna yapılan tüm referansları kaldırın. Örneğin:${ANDROID_NDK}/sources/android/native_app_glue/android_native_app_glue.c ... set(CMAKE_SHARED_LINKER_FLAGS "${CMAKE_SHARED_LINKER_FLAGS} -u ANativeActivity_onCreate")Kaynak kodu sürümünü kullanıyorsanız
GameActivitykaynak dosyalarını ekleyin. Aksi takdirde bu adımı atlayın.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)
UnsatisfiedLinkError sorununu çözme
com.google.androidgamesdk.GameActivity.initializeNativeCode() işlevi için UnsatsifiedLinkError ile karşılaşırsanız CMakeLists.txt dosyanıza şu kodu ekleyin:
set(CMAKE_SHARED_LINKER_FLAGS
"${CMAKE_SHARED_LINKER_FLAGS} -u \
Java_com_google_androidgamesdk_GameActivity_initializeNativeCode")
C/C++ kaynak kodu güncellemeleri
Uygulamanızdaki NativeActivity referanslarını GameActivity ile değiştirmek için aşağıdaki adımları uygulayın:
GameActivityile yayınlanannative_app_gluesürümünü kullanın. Tümandroid_native_app_glue.hkullanımlarını arayıp şununla değiştirin:#include <game-activity/native_app_glue/android_native_app_glue.h>Uygulamanızın tüm giriş cihazlarından giriş etkinlikleri alabilmesi için hem hareket etkinliği filtresini hem de önemli etkinlik filtresini
NULLolarak ayarlayın. Bu işlemi genellikleandroid_main()işlevi içinde yaparsınız: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. }AInputEventile ilgili kodu kaldırın ve GameActivity'ninInputBufferuygulamasıyla değiştirin: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_pollOnce(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; }NativeActivity'ye eklenen mantığı inceleyin ve güncelleyin
AInputEvent. Önceki adımda gösterildiği gibi, GameActivity'ninInputBufferişlemesiALooper_pollOnce()döngüsünün dışındadır.android_app::activity->clazzkullanımı yerineandroid_app:: activity->javaGameActivitykullanın. GameActivity, JavaGameActivityörneğini yeniden adlandırır.
Ek adımlar
Önceki adımlarda NativeActivity'nin işlevselliği ele alınmıştır ancak GameActivity'da kullanmak isteyebileceğiniz ek özellikler vardır:
- TextInput.
- Oyun kumandası.
- Fragment.
- NativeAppGlueAppCmd içinde tanımlanan yeni pencere InSets komutları.
Bu özellikleri incelemenizi ve oyunlarınızda uygun şekilde kullanmanızı öneririz.
GameActivity veya diğer AGDK kitaplıklarıyla ilgili sorularınız ya da önerileriniz varsa hata kaydı oluşturarak bize bildirin.