از قسمت NativeActivity کیت توسعه بازی اندروید مهاجرت کنید.
این صفحه نحوه مهاجرت از NativeActivity
به GameActivity
را در پروژه بازی اندروید خود شرح می دهد.
GameActivity
مبتنی بر NativeActivity
از فریم ورک اندروید است، با پیشرفتها و ویژگیهای جدید:
-
Fragment
از Jetpack پشتیبانی می کند. - برای تسهیل یکپارچه سازی صفحه کلید نرم، پشتیبانی
TextInput
را اضافه می کند. - رویدادهای لمسی و کلیدی را در کلاس
GameActivity
جاوا به جای رابطNativeActivity
onInputEvent
مدیریت می کند.
قبل از مهاجرت، توصیه میکنیم راهنمای شروع را مطالعه کنید، که نحوه راهاندازی و ادغام GameActivity
در پروژه را توضیح میدهد.
به روز رسانی اسکریپت ساخت جاوا
GameActivity
به عنوان یک کتابخانه Jetpack توزیع شده است. مطمئن شوید که مراحل بهروزرسانی اسکریپت Gradle را که در راهنمای شروع کار توضیح داده شده است، اعمال کنید:
کتابخانه Jetpack را در فایل
gradle.properties
پروژه خود فعال کنید:android.useAndroidX=true
به صورت اختیاری، یک نسخه Prefab را در همان فایل
gradle.properties
مشخص کنید، برای مثال:android.prefabVersion=2.0.0
ویژگی Prefab را در فایل
build.gradle
برنامه خود فعال کنید:android { ... // other configurations buildFeatures.prefab true }
وابستگی
GameActivity
به برنامه خود اضافه کنید:-
core
و کتابخانه هایgames-activity
را اضافه کنید. - اگر حداقل سطح API پشتیبانی شده فعلی شما کمتر از 16 است، آن را به حداقل 16 به روز کنید.
- نسخه SDK کامپایل شده را به نسخه ای که کتابخانه
games-activity
نیاز دارد، به روز کنید. Jetpack معمولاً در زمان انتشار به آخرین نسخه SDK نیاز دارد.
فایل
build.gradle
به روز شده شما ممکن است چیزی شبیه به این باشد: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' }
-
به روز رسانی کد کاتلین یا جاوا
NativeActivity
می تواند به عنوان یک فعالیت راه اندازی استفاده شود و یک برنامه تمام صفحه ایجاد کند. در حال حاضر، GameActivity نمی تواند به عنوان فعالیت راه اندازی استفاده شود. برنامه ها باید یک کلاس از GameActivity
گرفته و از آن به عنوان فعالیت راه اندازی استفاده کنند. همچنین برای ایجاد یک برنامه تمام صفحه باید تغییرات بیشتری در پیکربندی ایجاد کنید.
مراحل زیر فرض می کنند که برنامه شما از NativeActivity
به عنوان فعالیت راه اندازی استفاده می کند. اگر اینطور نیست، می توانید از بسیاری از آنها صرف نظر کنید.
یک فایل Kotlin یا Java برای میزبانی فعالیت راه اندازی جدید ایجاد کنید. برای مثال، کد زیر
MainActivity
به عنوان فعالیت راهاندازی ایجاد میکند و کتابخانه اصلی برنامه،libAndroidGame.so
را بارگیری میکند:کاتلین
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") } } }
جاوا
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.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>
تم را روی برنامه در فایل
AndroidManifest.xml
اعمال کنید:<application android:theme=”@style/Application.Fullscreen”> <!-- other configurations not listed here. --> </application>
برای دستورالعمل های دقیق برای حالت تمام صفحه، به راهنمای همهجانبه و اجرای نمونه در مخزن بازی-نمونه ها مراجعه کنید.
این راهنمای مهاجرت نام کتابخانه بومی را تغییر نمی دهد. اگر آن را تغییر میدهید، مطمئن شوید که نامهای کتابخانه بومی در سه مکان زیر مطابقت دارند:
کد کاتلین یا جاوا:
System.loadLibrary(“AndroidGame”)
AndroidManifest.xml
:<meta-data android:name="android.app.lib_name" android:value="AndroidGame" />
در داخل فایل اسکریپت ساخت C/C++، برای مثال
CMakeLists.txt
:add_library(AndroidGame ...)
به روز رسانی اسکریپت ساخت C/C++
دستورالعمل های این بخش cmake
به عنوان مثال استفاده می کنند. اگر برنامه شما از ndk-build
استفاده می کند، باید آنها را به دستورات معادل توضیح داده شده در صفحه مستندات ndk-build نگاشت کنید.
پیاده سازی C/C++ GameActivity یک کد منبع را ارائه کرده است. برای نسخه 1.2.2 بعدی، یک نسخه کتابخانه ایستا ارائه شده است. کتابخانه ایستا نوع انتشار توصیه شده است.
نسخه در داخل AAR با ابزار prefab
بسته بندی شده است. کد بومی شامل منابع C/C++ GameActivity و کد native_app_glue
است. آنها باید همراه با کد C/C++ برنامه شما ساخته شوند.
برنامههای NativeActivity
قبلاً از کد native_app_glue
ارسال شده در NDK استفاده میکنند. باید آن را با نسخه native_app_glue
GameActivity جایگزین کنید. به غیر از آن، تمام مراحل cmake
مستند در راهنمای شروع کار اعمال می شود:
کتابخانه ایستا C/C++ یا کد منبع C/++ را به صورت زیر وارد پروژه خود کنید.
کتابخانه ایستا
در فایل
CMakeLists.txt
پروژه خود، کتابخانه استاتیکgame-activity
را به ماژول prefabgame-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)
تمام ارجاعات به کد
native_app_glue
NDK را حذف کنید ، مانند:${ANDROID_NDK}/sources/android/native_app_glue/android_native_app_glue.c ... set(CMAKE_SHARED_LINKER_FLAGS "${CMAKE_SHARED_LINKER_FLAGS} -u ANativeActivity_onCreate")
اگر از نسخه کد منبع استفاده میکنید، فایلهای منبع
GameActivity
را نیز اضافه کنید. در غیر این صورت از این مرحله صرف نظر کنید.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 را حل کنید
اگر برای تابع com.google.androidgamesdk.GameActivity.initializeNativeCode()
با UnsatsifiedLinkError
مواجه شدید، این کد را به فایل CMakeLists.txt
خود اضافه کنید:
set(CMAKE_SHARED_LINKER_FLAGS
"${CMAKE_SHARED_LINKER_FLAGS} -u \
Java_com_google_androidgamesdk_GameActivity_initializeNativeCode")
به روز رسانی کد منبع C/C++
این مراحل را برای جایگزینی مراجع NativeActivity
در برنامه خود با GameActivity
دنبال کنید:
از
native_app_glue
منتشر شده باGameActivity
استفاده کنید. جستجو و جایگزینی تمام موارد استفادهandroid_native_app_glue.h
با:#include <game-activity/native_app_glue/android_native_app_glue.h>
فیلتر رویداد حرکتی و فیلتر رویداد کلیدی را روی
NULL
تنظیم کنید تا برنامه شما بتواند رویدادهای ورودی را از همه دستگاههای ورودی دریافت کند. شما معمولاً این کار را در تابعandroid_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. }
کد مربوط به
AInputEvent
را حذف کرده و با اجرایInputBuffer
GameActivity جایگزین کنید: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; }
منطق پیوست شده به
AInputEvent
NativeActivity را بررسی و بهروزرسانی کنید. همانطور که در مرحله قبل نشان داده شد، پردازشInputBuffer
GameActivity خارج از حلقهALooper_pollAll()
است.android_app::activity->clazz
usage را باandroid_app:: activity->javaGameActivity
جایگزین کنید. GameActivity نمونه JavaGameActivity
را تغییر نام می دهد.
مراحل اضافی
مراحل قبلی عملکرد NativeActivity را پوشش می دهد، اما GameActivity
دارای ویژگی های اضافی است که ممکن است بخواهید از آنها استفاده کنید:
- TextInput .
- کنترلر بازی
- قطعه .
- پنجره جدید دستورات InSets تعریف شده در NativeAppGlueAppCmd .
توصیه میکنیم این ویژگیها را بررسی کنید و آنها را متناسب با بازیهای خود بکار ببرید.
اگر سؤال یا توصیهای برای GameActivity یا سایر کتابخانههای AGDK دارید، یک اشکال ایجاد کنید تا به ما اطلاع دهید.