GameActivity'yi kullanmaya başlayın Android Oyun Geliştirme Kiti'nin bir parçasıdır.
Bu kılavuzda, kurulum ve entegrasyon işlemleri açıklanmaktadır.
GameActivity
ve Android cihazınızdaki etkinlikleri işleyin
bir oyundur.
GameActivity
, C veya
kritik API'ları kullanma sürecini basitleştirerek Android'e C++ oyunu kazandırdı.
Önceki NativeActivity
:
oyunlar için önerilen sınıf. GameActivity
, bu yeri önerilen olarak değiştirir
için geliştirilmiştir ve API düzeyi 19'a kadar geriye dönük uyumludur.
GameActivity'yi entegre eden bir örnek için şuraya bakın: oyun örnekleri deposu'na gidin.
Başlamadan önce
Şu dillere ait GameActivity
sürüme göz atın:
bir dağılım elde edersiniz.
Derlemenizi ayarlayın
Android'de giriş olarak Activity
kullanılır
sağlar ve aynı zamanda kullanıcılara
Çizim için Window
. Birçok oyun
sınırlamaları aşmak için kendi Java veya Kotlin sınıfıyla bu Activity
Köprü için JNI
kodu kullanılırken NativeActivity
C veya C++ oyun kodlarına ekliyorlar.
GameActivity
aşağıdaki özellikleri sunar:
Devralındığı kaynak
AppCompatActivity
Böylece, Android Jetpack Architecture Bileşenler'i tıklayın.Dönüştürülen
SurfaceView
ile şunları yapabilirsiniz: diğer Android kullanıcı arayüzü öğeleriyle kullanıcı arayüzünü ziyaret edin.Java etkinliği etkinliklerini yönetir. Bu, herhangi bir Android kullanıcı arayüzü öğesine (ör.
EditText
, birWebView
veya birAd
) olacak şekilde C arayüzü aracılığıyla oyununuza entegre edebilirsiniz.Şuna benzer bir C API sunar:
NativeActivity
veandroid_native_app_glue
kitaplığını açar.
GameActivity
, Android Arşivi olarak dağıtılır
(AAR). Bu AAR, şunu içeren Java sınıfını içerir:
anahtar kelime olarak
AndroidManifest.xml
ve C
ve GameActivity
ürününün Java tarafını uygulamanın
C/C++ uygulaması. GameActivity
1.2.2 veya daha yeni bir sürüm kullanıyorsanız C/C++
statik kitaplık da sağlanır. Geçerli olduğu durumlarda
kaynak kodu yerine statik kitaplıktan yararlanır.
Bu kaynak dosyaları veya statik kitaplığı
DMAIC ve Yalın Altı Sigma yaklaşımı
Prefab
Böylece, yerel kitaplıkları ve kaynak kodunu
CMake project veya NDK derlemesi.
Şu adresteki talimatları uygulayın: Jetpack Android Games sayfasında Oyununuzun
build.gradle
dosyasınaGameActivity
kitaplık bağımlılığı.Aşağıdakileri şununla yaparak prefab'i etkinleştirin: Android Eklenti Sürümü (AGP) 4.1+:
- Aşağıdakini, modülünüzün
build.gradle
dosyasınınandroid
bloğuna ekleyin:
buildFeatures { prefab true }
- Prefab sürümü seçin.
ve
gradle.properties
dosyasına ayarlayın:
android.prefabVersion=2.0.0
Önceki AGP sürümlerini kullanıyorsanız prefab belgelerine göz atın sayfasına bakın.
- Aşağıdakini, modülünüzün
C/C++ statik kitaplığını veya C/++ kaynak kodunu takip etmeniz gerekir.
Statik kitaplık
Projenizin
CMakeLists.txt
dosyasınagame-activity
statikgame-activity_static
prefab modülüne ekledik:find_package(game-activity REQUIRED CONFIG) target_link_libraries(${PROJECT_NAME} PUBLIC log android game-activity::game-activity_static)
Kaynak kodu
Projenizin
CMakeLists.txt
dosyasınagame-activity
pakete ekleyip hedefinize ekleyin.game-activity
paketi için gerekenlerlibandroid.so
; eksikse dosyayı da içe aktarmanız gerekir.find_package(game-activity REQUIRED CONFIG) ... target_link_libraries(... android game-activity::game-activity)
Ayrıca projenizin
CmakeLists.txt
dosyasına aşağıdaki dosyaları da ekleyin:GameActivity.cpp
,GameTextInput.cpp
veandroid_native_app_glue.c
.
Android, Etkinliğinizi nasıl başlatır?
Android sistemi, geri çağırma işlemini çağırarak Etkinlik örneğinizde kodu yürütür belirli aşamalara karşılık gelen yöntemlerle ilişkilendirilir. Siparişte uygulamanızı başlatması için izin vermeniz durumunda, Android Manifest'te uygun özelliklerle yapmanızı öneririz. Daha fazla bkz. Etkinliklere Giriş.
Android Manifesti
Her uygulama projesinin AndroidManifest.xml dosyasını kökünü oluşturur. Manifest dosyası, Android derleme araçları, Android işletim sistemi ve sistemi ve Google Play. Bu güvenlik özelliklerinden bazıları şunlardır:
Paket adı ve uygulama kimliği oyunlarınızı Google Play'de benzersiz şekilde tanımlamak için kullanılır.
Uygulama Bileşenleri: etkinlikler, hizmetler, yayın alıcıları ve içerik sağlayıcılar.
Erişim için izinler veya diğer uygulamaların korunan kısımlarına karşı korumanız gerekir.
Cihaz uyumluluğu hem de oyununuz için donanım ve yazılım gereksinimlerini belirleyebilirsiniz.
GameActivity
veNativeActivity
için yerel kitaplık adı(varsayılan olarak libmain.so) kullanılır.
Oyununuzda GameActivity'yi uygulayın
Ana etkinlik Java sınıfınızı (
activity
öğesiAndroidManifest.xml
dosyanızın içinde bulunur). Bu sınıfı şu şekilde değiştir:com.google.androidgamesdk
paketindenGameActivity
uzat:import com.google.androidgamesdk.GameActivity; public class YourGameActivity extends GameActivity { ... }
Yerel kitaplığınızın başlangıçta statik blok kullanarak yüklendiğinden emin olun:
public class EndlessTunnelActivity extends GameActivity { static { // Load the native library. // The name "android-game" depends on your CMake configuration, must be // consistent here and inside AndroidManifect.xml System.loadLibrary("android-game"); } ... }
Yerel kitaplığınızı
AndroidManifest.xml
'e ekleme kitaplığınızın adı varsayılan ad (libmain.so
) değilse:<meta-data android:name="android.app.lib_name" android:value="android-game" />
android_main uygulama
android_native_app_glue
kitaplığı,GameActivity
yaşam döngüsü olaylarını ayrı bir iş parçacığında yönetmek için engellemek için Search Ads 360'ı kullanın. Kitaplığı kullanırken Dokunmatik giriş gibi yaşam döngüsü olaylarını işlemek için geri çağırmayı kaydedersiniz etkinlikler.GameActivity
arşivi kendi sürümünü içerirandroid_native_app_glue
kitaplığı için mevcut sürümü kullanamazsınız NDK sürümleri. Oyunlarınızandroid_native_app_glue
kitaplığını kullanıyorsaGameActivity
sürümüne geçin.android_native_app_glue
kitaplığı kaynak kodunuGameActivity
ile arayüz oluşturur. Şu ada sahip bir fonksiyonu uygulayın:android_main
, başlangıç noktası olarak kullanılır. Geçen yılandroid_app
adlı yapıyı oluşturur. Bu, oyununuza ve motorunuza göre değişiklik gösterebilir. Aşağıda bununla ilgili bir örnek verilmiştir:#include <game-activity/native_app_glue/android_native_app_glue.h> extern "C" { void android_main(struct android_app* state); }; void android_main(struct android_app* app) { NativeEngine *engine = new NativeEngine(app); engine->GameLoop(); delete engine; }
android_app
işlemini ana oyun döngünüzde (ör. yoklama ve yürütme) işleyin. NativeAppGlueAppCmd'de tanımlanan uygulama döngüsü etkinlikleri. Örneğin, aşağıdaki snippet_hand_cmd_proxy
işleviniNativeAppGlueAppCmd
işleyicisi, daha sonra uygulama döngüsü etkinliklerini yoklar ve bunları işleme için kayıtlı işleyici(android_app::onAppCmd
dilinde):void NativeEngine::GameLoop() { mApp->userData = this; mApp->onAppCmd = _handle_cmd_proxy; // register your command handler. mApp->textInputState = 0; while (1) { int events; struct android_poll_source* source; // If not animating, block until we get an event; // If animating, don't block. while ((ALooper_pollAll(IsAnimating() ? 0 : -1, NULL, &events, (void **) &source)) >= 0) { if (source != NULL) { // process events, native_app_glue internally sends the outstanding // application lifecycle events to mApp->onAppCmd. source->process(source->app, source); } if (mApp->destroyRequested) { return; } } if (IsAnimating()) { DoFrame(); } } }
Daha fazla bilgi edinmek için Sonsuz Tünel'in nasıl uygulandığını inceleyin NDK örneği. Temel fark, etkinliklerin aşağıda gösterildiği gibi nasıl işleneceğidir: ele alacağız.
Etkinlikleri yönetme
Giriş etkinliklerinin uygulamanıza ulaşmasını etkinleştirmek için etkinliğinizi oluşturup kaydedin
android_app_set_motion_event_filter
içeren filtreler
ve android_app_set_key_event_filter
.
Varsayılan olarak native_app_glue
kitaplığı yalnızca şu kameralardaki hareket etkinliklerine izin verir:
KAYNAK_DOKUNMA EKRANI
giriş. Referans belgeyi incelemeyi unutmayın.
ve android_native_app_glue
uygulama koduna bakın.
Giriş etkinliklerini işlemek için şunu içeren bir android_input_buffer
referansı alın:
android_app_swap_input_buffers()
her bir görev için geçerlidir. Bunlar, en son gerçekleştirildiği zamandan bu yana gerçekleşen hareket etkinliklerini ve önemli etkinlikleri içerir.
anket yapıldı. İçerdiği etkinliklerin sayısı motionEventsCount
içinde depolanır ve
Sırasıyla keyEventsCount
.
Oyun döngünüzdeki her etkinliği yineleyin ve yönetin. Bu örnekte aşağıdaki kod
motionEvents
işlemini yineler ve bunlarıhandle_event
üzerinden işler:android_input_buffer* inputBuffer = android_app_swap_input_buffers(app); if (inputBuffer && inputBuffer->motionEventsCount) { for (uint64_t i = 0; i < inputBuffer->motionEventsCount; ++i) { GameActivityMotionEvent* motionEvent = &inputBuffer->motionEvents[i]; if (motionEvent->pointerCount > 0) { const int action = motionEvent->action; const int actionMasked = action & AMOTION_EVENT_ACTION_MASK; // Initialize pointerIndex to the max size, we only cook an // event at the end of the function if pointerIndex is set to a valid index range uint32_t pointerIndex = GAMEACTIVITY_MAX_NUM_POINTERS_IN_MOTION_EVENT; struct CookedEvent ev; memset(&ev, 0, sizeof(ev)); ev.motionIsOnScreen = motionEvent->source == AINPUT_SOURCE_TOUCHSCREEN; if (ev.motionIsOnScreen) { // use screen size as the motion range ev.motionMinX = 0.0f; ev.motionMaxX = SceneManager::GetInstance()->GetScreenWidth(); ev.motionMinY = 0.0f; ev.motionMaxY = SceneManager::GetInstance()->GetScreenHeight(); } switch (actionMasked) { case AMOTION_EVENT_ACTION_DOWN: pointerIndex = 0; ev.type = COOKED_EVENT_TYPE_POINTER_DOWN; break; case AMOTION_EVENT_ACTION_POINTER_DOWN: pointerIndex = ((action & AMOTION_EVENT_ACTION_POINTER_INDEX_MASK) >> AMOTION_EVENT_ACTION_POINTER_INDEX_SHIFT); ev.type = COOKED_EVENT_TYPE_POINTER_DOWN; break; case AMOTION_EVENT_ACTION_UP: pointerIndex = 0; ev.type = COOKED_EVENT_TYPE_POINTER_UP; break; case AMOTION_EVENT_ACTION_POINTER_UP: pointerIndex = ((action & AMOTION_EVENT_ACTION_POINTER_INDEX_MASK) >> AMOTION_EVENT_ACTION_POINTER_INDEX_SHIFT); ev.type = COOKED_EVENT_TYPE_POINTER_UP; break; case AMOTION_EVENT_ACTION_MOVE: { // Move includes all active pointers, so loop and process them here, // we do not set pointerIndex since we are cooking the events in // this loop rather than at the bottom of the function ev.type = COOKED_EVENT_TYPE_POINTER_MOVE; for (uint32_t i = 0; i < motionEvent->pointerCount; ++i) { _cookEventForPointerIndex(motionEvent, callback, ev, i); } break; } default: break; } // Only cook an event if we set the pointerIndex to a valid range, note that // move events cook above in the switch statement. if (pointerIndex != GAMEACTIVITY_MAX_NUM_POINTERS_IN_MOTION_EVENT) { _cookEventForPointerIndex(motionEvent, callback, ev, pointerIndex); } } } android_app_clear_motion_events(inputBuffer); }
Bkz. GitHub örneği
_cookEventForPointerIndex()
ve diğer özelliklerin uygulanması için benzer işlevler sunar.İşiniz bittiğinde, az önce tamamladığınız etkinlik sırasını temizlemeyi işlenen:
android_app_clear_motion_events(mApp);
Ek kaynaklar
GameActivity
hakkında daha fazla bilgi edinmek için aşağıdakilere göz atın:
- GameActivity ve AGDK sürüm notları
- GameActivity'de GameTextInput'u kullanın.
- NativeActivity taşıma rehberi.
- GameActivity referans belgeleri.
- Oyun Etkinliği uygulaması.
Hataları bildirmek veya GameActivity'ye yeni özellikler eklemek için GameActivity Sorun İzleyici'yi kullanın.