GameActivity का इस्तेमाल शुरू करना Android गेम डेवलपमेंट किट का हिस्सा.
इस गाइड में, Google Analytics खाते को सेट अप और इंटिग्रेट करने का तरीका बताया गया है
GameActivity
और अपने Android में इवेंट मैनेज करना
गेम.
GameActivity
की मदद से, C या
ज़रूरी एपीआई इस्तेमाल करने की प्रोसेस को आसान बनाकर, C++ गेम खेलें.
पहले NativeActivity
यह था
गेम के लिए सुझाई गई क्लास. GameActivity
इसे सुझाए गए के रूप में बदल देता है
क्लास के साथ काम करता है. साथ ही, यह एपीआई लेवल 19 के साथ काम करता है.
GameActivity को इंटिग्रेट करने वाले सैंपल के लिए, यह देखें गेम के सैंपल का डेटा स्टोर करने की जगह.
शुरू करने से पहले
इनके लिए, GameActivity
रिलीज़ देखें
एक डिस्ट्रिब्यूशन पाएं.
अपना बिल्ड सेट अप करें
Android पर, Activity
एंट्री के तौर पर काम करता है
पॉइंट देता है. साथ ही, आपको
Window
का इस्तेमाल करें. कई गेम में
सीमाओं से आगे निकलने के लिए, अपने Java या Kotlin क्लास के साथ यह Activity
ब्रिज करने के लिए JNI
कोड का इस्तेमाल करते समय NativeActivity
C या C++ गेम कोड जोड़ सकते हैं.
GameActivity
में ये सुविधाएं मिलती हैं:
इनसे इनहेरिट करता है
AppCompatActivity
इससे Android Jetpack आर्किटेक्चर का इस्तेमाल किया जा सकता है कॉम्पोनेंट.इस तरह के कॉन्टेंट में रेंडर हो जाता है
SurfaceView
की मदद से, ये काम किए जा सकते हैं किसी अन्य Android यूज़र इंटरफ़ेस (यूआई) एलिमेंट के साथ इंटरफ़ेस करने के लिए डिज़ाइन किया गया है.Java की गतिविधि के इवेंट मैनेज करता है. इससे किसी भी Android यूज़र इंटरफ़ेस (यूआई) एलिमेंट (जैसे कि
EditText
,WebView
याAd
) को गेम को सी इंटरफ़ेस के ज़रिए इंटिग्रेट किया गया है.इससे मिलता-जुलता C API ऑफ़र करता है
NativeActivity
, औरandroid_native_app_glue
लाइब्रेरी.
GameActivity
को Android संग्रह के तौर पर उपलब्ध कराया गया है
(एएआर). इस एएआर में वह Java क्लास शामिल है जो
अपने
AndroidManifest.xml
और C
और C++ सोर्स कोड का इस्तेमाल करें, जो GameActivity
के Java साइड को ऐप्लिकेशन के
C/C++ लागू करना. अगर आप GameActivity
के 1.2.2 या उसके बाद के वर्शन का इस्तेमाल कर रहे हैं, तो C/C++
स्टैटिक लाइब्रेरी भी दी जाती है. हमारा सुझाव है कि जहां भी लागू हो,
और सोर्स कोड के बजाय स्टैटिक लाइब्रेरी का इस्तेमाल करें.
इन सोर्स फ़ाइलों या स्टैटिक लाइब्रेरी को अपने
बिल्ड प्रोसेस शुरू करें.
Prefab
जो आपकी साइट पर नेटिव लाइब्रेरी और सोर्स कोड दिखाता है
CMake Project या NDK बिल्ड.
इसके लिए, Jetpack Android Games पेज पर जाकर
GameActivity
लाइब्रेरी डिपेंडेंसी आपके गेम कीbuild.gradle
फ़ाइल पर निर्भर करती है.इनके साथ ये काम करके प्रीफ़ैब को चालू करें Android प्लग इन वर्शन (AGP) 4.1+:
- अपने मॉड्यूल की
build.gradle
फ़ाइल केandroid
ब्लॉक में ये जोड़ें:
buildFeatures { prefab true }
- कोई Prefab वर्शन चुनें,
और इसे
gradle.properties
फ़ाइल पर सेट करें:
android.prefabVersion=2.0.0
अगर एजीपी के पुराने वर्शन इस्तेमाल किए जाते हैं, तो फ़ॉलो करें प्रीफ़ैब दस्तावेज़ देखें.
- अपने मॉड्यूल की
C/C++ स्थैतिक लाइब्रेरी या C/++ स्रोत कोड किया गया है.
स्टैटिक लाइब्रेरी
अपने प्रोजेक्ट की
CMakeLists.txt
फ़ाइल में,game-activity
स्टैटिक इंपोर्ट करें लाइब्रेरी कोgame-activity_static
प्रीफ़ैब मॉड्यूल में लाया है:find_package(game-activity REQUIRED CONFIG) target_link_libraries(${PROJECT_NAME} PUBLIC log android game-activity::game-activity_static)
सोर्स कोड
अपने प्रोजेक्ट की
CMakeLists.txt
फ़ाइल में,game-activity
को इंपोर्ट करें पैकेज तैयार करना है और उसे अपने टारगेट में जोड़ना है.game-activity
पैकेज के लिए ज़रूरी हैlibandroid.so
, इसलिए अगर यह मौजूद नहीं है, तो आपको इसे भी इंपोर्ट करना होगा.find_package(game-activity REQUIRED CONFIG) ... target_link_libraries(... android game-activity::game-activity)
साथ ही, अपने प्रोजेक्ट के
CmakeLists.txt
में ये फ़ाइलें भी शामिल करें:GameActivity.cpp
,GameTextInput.cpp
, औरandroid_native_app_glue.c
.
Android आपकी ऐक्टिविटी को कैसे लॉन्च करता है
Android सिस्टम, कॉलबैक को शुरू करके आपके ऐक्टिविटी इंस्टेंस में कोड लागू करता है गतिविधियों की लाइफ़साइकल के खास चरणों से जुड़े तरीके. ऑर्डर में शामिल है Android को आपकी गतिविधि लॉन्च करने और गेम शुरू करने के लिए, आपको Android मेनिफ़ेस्ट में सही एट्रिब्यूट के साथ आपकी गतिविधि शामिल है. ज़्यादा के लिए जानकारी, देखें गतिविधियों के बारे में जानकारी.
Android मेनिफ़ेस्ट
हर ऐप्लिकेशन प्रोजेक्ट में AndroidManifest.xml फ़ाइल में प्रोजेक्ट सोर्स सेट का रूट (रूट) है. मेनिफ़ेस्ट फ़ाइल में दी गई ज़रूरी जानकारी Android बिल्ड टूल, Android के काम करने के तरीके, और ऐप्लिकेशन के बारे में जानकारी और Google Play शामिल हैं. इसमें ये शामिल हैं:
पैकेज का नाम और ऐप्लिकेशन आईडी आपके गेम को खास तौर पर पहचानने के लिए.
ऐप्लिकेशन कॉम्पोनेंट, जैसे कि गतिविधियां, सेवाएं, ब्रॉडकास्ट रिसीवर, और कॉन्टेंट उपलब्ध कराने वाली कंपनियां.
ऐक्सेस करने के लिए अनुमतियां सिस्टम या अन्य ऐप्लिकेशन के सुरक्षित हिस्सों को सुरक्षित रखने में मदद करता है.
Google Kids Space इन डिवाइसों पर काम करता है आपके गेम के लिए हार्डवेयर और सॉफ़्टवेयर की ज़रूरतें बताने के लिए.
GameActivity
औरNativeActivity
के लिए, लाइब्रेरी का मूल नाम(डिफ़ॉल्ट रूप से यह libmain.so है).
अपने गेम में GameActivity लागू करें
अपनी मुख्य गतिविधि Java क्लास (जिसे आपकी
AndroidManifest.xml
फ़ाइल मेंactivity
एलिमेंट है). इस क्लास को इसमें बदलेंcom.google.androidgamesdk
पैकेज सेGameActivity
बढ़ाएं:import com.google.androidgamesdk.GameActivity; public class YourGameActivity extends GameActivity { ... }
पक्का करें कि आपकी नेटिव लाइब्रेरी, स्टैटिक ब्लॉक का इस्तेमाल करके शुरू में लोड की गई हो:
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"); } ... }
अपनी स्थानीय लाइब्रेरी को
AndroidManifest.xml
में जोड़ें अगर आपकी लाइब्रेरी का नाम डिफ़ॉल्ट नाम (libmain.so
) नहीं है, तो:<meta-data android:name="android.app.lib_name" android:value="android-game" />
android_main को लागू करें
android_native_app_glue
लाइब्रेरी, सोर्स कोड की लाइब्रेरी है गेम,GameActivity
लाइफ़साइकल इवेंट को एक अलग थ्रेड में मैनेज करने के लिए इसका इस्तेमाल करता है ताकि वे आपके मुख्य थ्रेड को ब्लॉक न कर सकें. लाइब्रेरी का इस्तेमाल करते समय, टच इनपुट जैसे लाइफ़साइकल इवेंट को मैनेज करने के लिए, कॉलबैक को रजिस्टर किया जाता है इवेंट.GameActivity
संग्रह मेंandroid_native_app_glue
लाइब्रेरी, ताकि आप इसमें शामिल वर्शन का इस्तेमाल न कर सकें एनडीके (NDK) रिलीज़. अगर आपके गेमandroid_native_app_glue
लाइब्रेरी का इस्तेमाल कर रहे हैं जो एनडीके में शामिल है, तोGameActivity
वर्शन पर स्विच करें.android_native_app_glue
लाइब्रेरी का सोर्स कोड, अपने प्रोजेक्ट है, तो यहGameActivity
से इंटरफ़ेस करता है. नाम वाला फ़ंक्शन लागू करेंandroid_main
, जिसे लाइब्रेरी और आपके गेम के एंट्री पॉइंट के तौर पर इस्तेमाल किया जाता है. इसनेandroid_app
नाम का स्ट्रक्चर. यह आपके गेम और इंजन के लिए अलग हो सकता है. यहां एक उदाहरण दिया गया है:#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
को अपने मुख्य गेम लूप में प्रोसेस करें, जैसे कि पोल और हैंडलिंग NativeAppGlueAppCmd में बताए गए ऐप्लिकेशन साइकल इवेंट. उदाहरण के लिए, नीचे दिया गया स्निपेट फ़ंक्शन_hand_cmd_proxy
कोNativeAppGlueAppCmd
हैंडलर, फिर पोल ऐप्लिकेशन के साइकल इवेंट को ट्रिगर करता है और उन्हें प्रोसेसिंग के लिए रजिस्टर किया गया हैंडलर(android_app::onAppCmd
में):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(); } } }
आगे पढ़ने के लिए, एंडलेस टनल लागू करने के तरीके को जानें NDK का उदाहरण. मुख्य अंतर यह होगा कि इवेंट को किस तरह से मैनेज किया जाए, जैसा कि यहां दिखाया गया है अगला सेक्शन देखें.
इवेंट मैनेज करना
अपने ऐप्लिकेशन तक पहुंचने के लिए, इनपुट इवेंट चालू करने के लिए, इवेंट बनाएं और रजिस्टर करें
android_app_set_motion_event_filter
वाले फ़िल्टर
और android_app_set_key_event_filter
.
डिफ़ॉल्ट रूप से, native_app_glue
लाइब्रेरी सिर्फ़ मोशन इवेंट की अनुमति देती है
SOURCE_TOUCHSCREEN
इनपुट. पहचान दस्तावेज़ को देखना न भूलें
और जानकारी के लिए android_native_app_glue
इंप्लिमेंटेशन कोड.
इनपुट इवेंट मैनेज करने के लिए, इसके साथ android_input_buffer
का रेफ़रंस पाएं
android_app_swap_input_buffers()
गेम लूप में चलाएं. इनमें मोशन इवेंट और मुख्य इवेंट शामिल होते हैं. ये इवेंट पिछली बार होने के बाद से हुए हैं
पोल किया गया. शामिल इवेंट की संख्या motionEventsCount
में सेव की जाती है, और
keyEventsCount
.
अपने गेम लूप में, हर इवेंट को दोहराएं और मैनेज करें. इस उदाहरण में, यह कोड
motionEvents
को इटरेट करता है और उन्हेंhandle_event
के ज़रिए हैंडल करता है: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); }
ज़्यादा जानकारी के लिए, GitHub सैंपल
_cookEventForPointerIndex()
और अन्य मिलते-जुलते फ़ंक्शन.काम पूरा हो जाने के बाद, उन इवेंट की सूची को हटाना न भूलें जो आपके पास हैं हैंडल किया जाने वाला:
android_app_clear_motion_events(mApp);
अन्य संसाधन
GameActivity
के बारे में ज़्यादा जानने के लिए, यह लेख देखें:
- GameActivity और एजीडीके की जानकारी.
- GameActivity में GameTextइनपुट का इस्तेमाल करना.
- NativeActivity माइग्रेशन गाइड.
- GameActivity के रेफ़रंस के लिए दस्तावेज़.
- GameActivity लागू करना.
GameActivity में बग की शिकायत करने या नई सुविधाओं का अनुरोध करने के लिए, GameActivity से जुड़ी समस्या को ट्रैक करने वाला टूल इस्तेमाल करें.