هنگام توسعه یک بازی برای اندروید، پیشبینی تنوع تجربیات ممکن بازیکن و سازگاری با نیازهای تعاملی بلادرنگ بازیکن بسیار مهم است. با پشتیبانی از تجربیات مختلف بازیکن، انعطافپذیری گیمپلی را افزایش میدهید و به شما در گسترش دامنه بازیتان کمک میکند.
تفاوتهای خاص در تجربه بازیکن شامل موارد زیر است:
- فرم فاکتور دستگاه: اگرچه تلفنها تجربه سنتی دستگاههای اندرویدی را ارائه میدهند، اما میتوان با بازیها در فرم فاکتورهای دیگر نیز تعامل داشت. دستگاههای ChromeOS میتوانند یک کانتینر اندرویدی را اجرا کنند که بازی شما را نمایش میدهد. تبلتهایی که میتوانند اندروید را اجرا کنند، از چندین سطح مختلف از وفاداری پشتیبانی میکنند. دستگاههای Android TV از تجربیات غنیتر و فراگیرتر پشتیبانی میکنند. بازیکنان میتوانند با استفاده از یک ابزار افزونه نمایشگر، یک محیط چند پنجرهای را شبیهسازی کنند. و هنگام استفاده از دستگاههای تاشو، بازیکنان میتوانند اندازه صفحه را در طول یک جلسه گیمپلی تغییر دهند.
- روشهای تعامل: بازیکنان میتوانند با لمس صفحه نمایش دستگاه، اطلاعات را ارائه دهند، اما میتوانند به جای آن از ماوس، تاچپد، صفحهکلید یا کنترلر نیز استفاده کنند. علاوه بر این، وجود ابزارهای توسعه نمایشگر و دستگاههای تاشو به بازیکنان این امکان را میدهد که بازی شما را روی صفحه نمایش بزرگتری تجربه کنند و جلسات گیمپلی طولانیتر و رابطهای کاربری پیچیدهتر را امکانپذیرتر کنند.
- پشتیبانی سختافزاری: برخی از دستگاههای اندروید سختافزاری که در دستگاههای دستی رایج است، مانند دوربین عقب، GPS و اتصال به شبکه را ندارند. بازی شما باید با سختافزار موجود سازگار شود و به خوبی از پس موقعیتهایی که برخی ویژگیها در دسترس نیستند، برآید.
این راهنما بهترین شیوههای مربوط به توسعه بازی شما برای انواع مختلف صفحه نمایش و تعاملات کاربری را ارائه میدهد. این راهنما همچنین پیشنهاداتی در مورد طراحی بازی شما و تدوین یک استراتژی تست موثر ارائه میدهد.
بهترین شیوههای طراحی بازی
هنگام برنامهریزی طراحی و معماری بازی خود، از بهترین شیوههای شرح داده شده در بخشهای بعدی پیروی کنید.
به تغییرات پیکربندی به صورت دستی پاسخ دهید
وقتی سیستم اندروید تغییر پیکربندی ، مانند تغییر در اندازه صفحه نمایش، جهت صفحه نمایش یا روش ورودی را تشخیص میدهد، سیستم به طور پیشفرض اکتیویتی فعلی را مجدداً راهاندازی میکند. برای حفظ وضعیت در یک برنامه یا بازی، اکتیویتی به طور پیشفرض قبل از راهاندازی مجدد، تابع onSaveInstanceState() و پس از راهاندازی مجدد، onRestoreInstanceState() فراخوانی میکند. با این حال، این فرآیند مستلزم آن است که اکتیویتی تمام سرویسها و منابع مرتبط را مجدداً بارگذاری کند. برای کسب اطلاعات بیشتر در مورد این رفتار پیشفرض، به راهنمای مدیریت تغییرات پیکربندی مراجعه کنید .
یک جلسه گیمپلی معمولی دستخوش چندین تغییر پیکربندی میشود. اگر بازی شما اجازه دهد سیستم هر تغییر پیکربندی را مدیریت کند، صحنه بازی شما بارها و بارها از بین میرود و مجدداً راهاندازی میشود و عملکرد بازی شما را کاهش میدهد. به همین دلیل، اکیداً توصیه میکنیم که خودتان این تغییرات پیکربندی را در بازی خود مدیریت کنید.
برای یادگیری نحوهی افزودن این منطق تغییر پیکربندی به بازی خود، به بخش نحوهی ایجاد کنترلکنندههای تغییر پیکربندی سفارشی مراجعه کنید .
ایجاد معماری انعطافپذیر
برای افزودن پشتیبانی از بازی خود در بیشترین تعداد دستگاه ممکن، این بهترین شیوهها را دنبال کنید:
- به جای APK های جداگانه، از بستههای نرمافزاری اندروید استفاده کنید. بستههای نرمافزاری اندروید به شما این امکان را میدهند که مصنوعات با وضوح تصویر و مدلهای معماری مختلف، مانند x86، ARM، را در یک مصنوع واحد بستهبندی کنید. از آن بهتر، بستههای نرمافزاری اندروید از محدودیتهای حجمی بالاتری برای بازی شما پشتیبانی میکنند؛ هر APK پایه میتواند تا ۱۵۰ مگابایت باشد و خود بسته میتواند چندین گیگابایت حجم داشته باشد.
- پشتیبانی از معماریهای x86 را اضافه کنید. این مرحله عملکرد بازی شما را در دستگاههایی که از ARM پشتیبانی نمیکنند بهبود میبخشد، زیرا این دستگاهها اکنون میتوانند دستورالعملها را بدون نیاز به ترجمه اولیه اجرا کنند.
اضافه شدن پشتیبانی از Vulkan
با پشتیبانی از Vulkan ، بازی شما میتواند به عملکرد گرافیکی بالاتری دست یابد. اکثر دستگاهها از این API گرافیکی پشتیبانی میکنند.
ایجاد کنترلکنندههای تغییر پیکربندی سفارشی
برای اعلام انواع تغییرات پیکربندی که بازی شما خودش مدیریت میکند، ویژگی android:configChanges به هر عنصر <activity> در مانیفست خود که نشاندهنده یک صفحه نمایش یا رابط کاربری پیچیده است، اضافه کنید.
قطعه کد زیر نشان میدهد که چگونه اعلام کنید که بازی شما از تغییرات اندازه صفحه، جهت صفحه و روش ورودی مراقبت میکند:
<activity ... android:configChanges="screenSize|orientation|keyboard|keyboardHidden"> </activity>
وقتی تغییرات پیکربندی اعلامشده رخ میدهد، سیستم اکنون متد متفاوتی به نام onConfigurationChanged() را فراخوانی میکند. درون این متد، منطقی را برای بهروزرسانی رابط کاربری بازی خود اضافه کنید:
- ضریب مقیاس و جهت صفحه را بهروزرسانی کنید. به خاطر داشته باشید که برای اهداف عملکردی، گاهی اوقات بهتر است رابط کاربری بازی خود را فقط در یک بعد مقیاسبندی کنید .
- روش ورودی بهینه برای استفاده بازیکن را مشخص کنید.
مدیریت تغییرات پیکربندی صفحه نمایش
بازی شما هر زمان که مقادیر screenSize و orientation را به ترتیب در ویژگی android:configChanges قرار دهید، تغییرات اندازه صفحه و جهت صفحه را به صورت دستی مدیریت میکند. میتوانید از این مقادیر جدید برای بهروزرسانی محتوای صحنه و قسمتهای ورودی بازیکن استفاده کنید. برای راهنمایی در مورد نحوه طراحی طرحبندی بازی خود برای آسانتر کردن بهروزرسانی، به راهنمای پشتیبانی از اندازههای مختلف صفحه مراجعه کنید .
در پیادهسازی تابع onConfigurationChanged() در بازی خود، از شیء Configuration ارسالی و شیء Display در مدیر پنجره برای تعیین مقادیر بهروزرسانیشده برای اندازه صفحه و جهت صفحه، به ترتیب، استفاده کنید.
قطعه کد زیر نحوهی دریافت اندازه و جهتگیری بهروزرسانیشدهی صفحهی بازی شما را نشان میدهد:
کاتلین
override fun onConfigurationChanged(newConfig: Configuration) { super.onConfigurationChanged(newConfig) val density: Float = resources.displayMetrics.density val newScreenWidthPixels = (newConfig.screenWidthDp * density).toInt() val newScreenHeightPixels = (newConfig.screenHeightDp * density).toInt() // Get general orientation; either Configuration.ORIENTATION_PORTRAIT or // Configuration.ORIENTATION_LANDSCAPE. val newScreenOrientation: Int = newConfig.orientation // Get general rotation; one of: ROTATION_0, ROTATION_90, ROTATION_180, // or ROTATION_270. val newScreenRotation: Int = windowManager.defaultDisplay.rotation }
جاوا
@Override public void onConfigurationChanged(Configuration newConfig) { super.onConfigurationChanged(newConfig); float density = getResources().getDisplayMetrics().density; int newScreenWidthPixels = (int) (newConfig.screenWidthDp * density); int newScreenHeightPixels = (int) (newConfig.screenHeightDp * density); // Get general orientation; either Configuration.ORIENTATION_PORTRAIT or // Configuration.ORIENTATION_LANDSCAPE. int newScreenOrientation = newConfig.orientation; // Get general rotation; one of: ROTATION_0, ROTATION_90, ROTATION_180, // or ROTATION_270. int newScreenRotation = getWindowManager().getDefaultDisplay() .getRotation(); }
توجه داشته باشید که تغییر حالت یک دستگاه تاشو، حتی اگر برنامه شما در حالت تمام صفحه اجرا شود، پیکربندی را تغییر میدهد. در نتیجه، اگر کاربر در حین اجرای بازی، دستگاه را تا یا باز کند، ممکن است برنامه شما مجبور شود تغییرات اندازه صفحه نمایش یا تراکم پیکسل را مدیریت کند.
کیفیت صفحه نمایش مخصوص بازی
بخشهای زیر نحوه تنظیم واکنش بازی شما به اندازه صفحه یا تغییرات جهت صفحه را بسته به ویژگیهای بازی شما شرح میدهند:
حالت تمام صفحه
در برخی پلتفرمها، مانند ChromeOS، برنامهها و بازیهای اندروید میتوانند به صورت پیشفرض به صورت پنجرهای و با قابلیت تغییر اندازه باشند. اگر بازی شما همیشه باید در حالت تمام صفحه اجرا شود، میتوانید ویژگی android:resizeableActivity را در یکی از عناصر <activity> خود، همانطور که در قطعه کد زیر نشان داده شده است، روی false تنظیم کنید:
<activity ... android:resizeableActivity="false"> </activity>
همچنین میتوانید ویژگی android:resizeableActivity را روی false تنظیم کنید تا از تغییرات پیکربندی مبتنی بر اندازه جلوگیری شود. با این حال، اگر بازی شما همیشه در حالت تمام صفحه اجرا نمیشود، باید این ویژگی را فقط به عنوان یک راه حل موقت برای اهداف آزمایشی اضافه کنید.
جهت گیری صفحه نمایش
اگر بازی شما به جهتگیری خاص حسگرهای دستگاه وابسته است، همانطور که در قطعه کد زیر نشان داده شده است، مقداری برای android:screenOrientation در activity بازی خود تعیین کنید. این تنظیم به جلوگیری از وارونه شدن غیرمنتظره صحنه در بازی شما کمک میکند.
<activity ... android:screenOrientation="landscape"> </activity>
کیفیت صفحه نمایش مخصوص دستگاه
بخشهای زیر نحوه مدیریت تغییرات پیکربندی مبتنی بر صفحه نمایش را با توجه به ویژگیهای خاص برخی دستگاهها شرح میدهند.
نسبت ابعاد
برخی از دستگاهها از نسبتهای ابعاد مختلفی پشتیبانی میکنند. به عنوان مثال، دستگاههای تاشو طوری طراحی شدهاند که در حالت تا شده از نسبت ابعاد ۲۱:۹ پشتیبانی کنند. برای مدیریت این تنوع بالقوه در نسبت ابعاد، حداقل یکی از موارد زیر را انجام دهید:
- اندروید ۸.۰ (سطح API ۲۶) یا بالاتر را هدف قرار دهید.
- صحنه و رابط کاربری بازی خود را قابل تغییر اندازه کنید. در دستگاههایی که اندروید ۷.۰ (سطح API 24) و بالاتر دارند،
android:resizeableActivityرا رویtrueتنظیم کنید. حداکثر نسبت ابعاد پشتیبانیشده را اعلام کنید. در ویژگی
<meta-data>مرتبط با بازی خود،android.max_aspectمطابق قطعه کد زیر روی2.4تنظیم کنید. با این حال، به خاطر داشته باشید که نسبت ابعاد بزرگتر از مقداری که مشخص کردهاید باعث میشود بازی در صفحه نمایش به صورت letterbox نمایش داده شود.<application> <meta-data android:name="android.max_aspect" android:value="2.4" /> </application>
چندین فعالیت به طور همزمان قابل مشاهده هستند
بسیاری از دستگاههای مدرن از طرحبندیهای مختلف صفحه نمایش، از جمله تقسیم صفحه، تصویر در تصویر و مناطق نمایش بزرگ پشتیبانی میکنند. هنگام استفاده از یکی از این طرحبندیها، سیستم میتواند چندین فعالیت را همزمان قابل مشاهده کند.
در دستگاههایی که اندروید ۹ (سطح API 28) یا بالاتر را اجرا میکنند، میتوان تمام فعالیتهای قابل مشاهدهی برتر را همزمان از سر گرفت. با این حال، برای اینکه این رفتار کار کند، هم بازی شما و هم سازندهی دستگاه باید این قابلیت را بپذیرند. میتوانید با تنظیم android.allow_multiple_resumed_activities روی true در فایل مانیفست بازی خود، همانطور که در قطعه کد زیر نشان داده شده است، پشتیبانی را در بازی خود اضافه کنید:
<application> <meta-data android:name="android.allow_multiple_resumed_activities" android:value="true" /> </application>
سپس میتوانید بازی خود را روی دستگاههای مختلف آزمایش کنید تا ببینید کدام یک از آنها پشتیبانی OEM لازم برای عملکرد صحیح multi-resume را ارائه میدهند.
برای اطلاعات بیشتر در مورد پیکربندی بازی خود برای نمایش به عنوان بخشی از نمایشگر چند پنجرهای، به راهنمای نحوه افزودن پشتیبانی از چند پنجره مراجعه کنید .
مدیریت انواع مختلف مدلهای تعاملی
بازی شما هر زمان که به ترتیب مقادیر keyboard و keyboardHidden را در ویژگی android:configChanges قرار دهید، حضور و در دسترس بودن صفحه کلید را به صورت دستی مدیریت میکند. میتوانید از این مقادیر جدید برای بهروزرسانی متد ورودی اصلی بازی خود استفاده کنید.
هنگام پیکربندی بازی خود برای پشتیبانی از انواع مختلف ورودی کاربر، موارد زیر را در نظر داشته باشید:
- تشخیص روشهای ورودی به جای دستگاههای منفرد. این طرز فکر، بهبود تجربه بازیکن را بدون تمرکز بیش از حد روی دستگاه خاصی که ممکن است بازیکن داشته باشد، آسانتر میکند.
- ویژگی
keyboardHiddenرا در فهرست تغییرات پیکربندی دستی خود قرار دهید. به این ترتیب، بازی شما میتواند پیگیری کند که چه زمانی یک صفحهکلید به صورت فیزیکی به دستگاه متصل است اما قابل استفاده نیست. روشهای ورودی موجود را تعیین کنید. برای انجام این کار، در هنگام شروع بازی و پس از هر تغییر پیکربندی، تابع
getInputDeviceIds()را فراخوانی کنید.شما اغلب میتوانید بر اساس دستگاه ورودی مورد نظر بازیکن، نحوه تعامل او با بازی را تعیین کنید:
- بازیکنان معمولاً از صفحه کلید یا دسته بازی برای انجام سریع دکمهها استفاده میکنند.
- بازیکنان معمولاً برای انجام حرکات پیچیدهتر از صفحه لمسی یا تاچپد استفاده میکنند.
- بازیکنان معمولاً برای انجام ورودیهای با دقت بالاتر از ماوس استفاده میکنند.
بخشهای زیر بهترین شیوهها را برای انواع خاصی از دستگاههای ورودی ارائه میدهند.
کیبورد
هنگام ایجاد طرحبندی صفحهکلید برای بازی خود، نحوه پیمایش بازیکن در یک صحنه مشخص و همچنین نحوه تعامل او با تنظیمات بازی خود را در نظر بگیرید.
کلیدهای WASD یا کلیدهای جهتنما معمولاً برای کنترل حرکت شخصیت بهترین هستند. همچنین بهتر است برای هر عمل یا مهارت مهمی که یک شخصیت قابل کنترل میتواند در بازی شما انجام دهد، یک کلید خاص اختصاص دهید. برای به حداکثر رساندن تجربه بازیکن، اضافه کردن پشتیبانی از اتصال کلیدهای سفارشی را در بازی خود در نظر بگیرید.
بازیکنان همچنین باید بتوانند منوهای بازی شما را باز کرده و با استفاده از صفحه کلید در آنها حرکت کنند. کلید Esc یک نگاشت رایج برای مکث یک صحنه و نمایش منوی بازی است.
برای اطلاعات بیشتر در مورد پشتیبانی از ورودی صفحه کلید در بازی خود، به راهنمای نحوه پشتیبانی از پیمایش صفحه کلید و همچنین راهنمای نحوه مدیریت عملکردهای صفحه کلید مراجعه کنید.
کنترل کننده بازی
برای اطلاعات بیشتر در مورد مدیریت ورودی کنترلر در بازی خود، به راهنمای نحوه پشتیبانی از کنترلرهای بازی مراجعه کنید .
ماوس یا صفحه لمسی
اگر بازی شما از ورودی بازیکن از طریق ماوس یا صفحه لمسی پشتیبانی میکند، به خاطر داشته باشید که بازیکنان به روشهای دیگری غیر از انجام بازی شما با دستگاه تعامل دارند. توجه به این نکته مهم است که با درخواست ضبط اشارهگر، تمام ورودیهای ماوس به بازی شما هدایت میشود. بنابراین، پس از اینکه بازی شما اطلاعات مورد نیاز خود را دریافت کرد، ضبط اشارهگر را رها کنید تا بازیکنان کنترل استاندارد ماوس دستگاه خود را دوباره به دست آورند.
در دستگاههایی که اندروید ۸.۰ (سطح API 26) و بالاتر را اجرا میکنند، میتوانید از رابط برنامهنویسی کاربردی Mouse Capture برای کمک به فرآیند گرفتن اشارهگر استفاده کنید. در بازیهایی که به ورودی با دقت بالا واکنش نشان میدهند، میتوانید مختصات فعلی اشارهگر را با فراخوانی متدهای getX() و getY() دریافت کنید.
برای اطلاعات بیشتر در مورد افزودن پشتیبانی از ورودی ماوس و ورودی تاچپد در بازی خود، به راهنمای نحوه ردیابی حرکات لمسی و اشارهگر و همچنین راهنمای نحوه مدیریت حرکات چند لمسی مراجعه کنید.
بازی خود را آزمایش کنید
قبل از اجرای بازی، با انجام مراحل شرح داده شده در بخشهای بعدی، نحوه واکنش آن به تغییرات پیکربندی را آزمایش کنید.
برنامه آزمون خود را بهروز کنید
هنگام اعتبارسنجی عملکرد بازی خود، موارد آزمایشی زیر را لحاظ کنید:
- پنجرهای که بازی شما در آن قرار دارد را کوچک و بزرگ کنید. (اگر بازی شما همیشه در حالت تمام صفحه باشد، این گزینه اعمال نمیشود.)
- تغییر اندازه صفحه نمایش.
- تغییر جهت صفحه نمایش. (اگر بازی شما جهت ثابتی دارد، این مورد اعمال نمیشود.)
- دستگاههای ورودی مانند صفحهکلید و ماوس را وصل و جدا کنید.
- اگر بازی شما از آن پشتیبانی میکند، از قابلیت چند-رزومهای (multi-resume) استفاده کنید.
همچنین، بهروزرسانی سیستم کنترل کیفیت بازی خود را در نظر بگیرید تا بتوانید آن را برای طیف وسیعتری از تجربیات بازیکنان بهینهسازی کنید.
برای بهترین شیوههای مربوط به آزمایش بازی خود، به راهنمای اصول آزمایش مراجعه کنید.
استفاده از ابزارهای تست و اشکالزدایی
شما میتوانید با استفاده از ابزارهای متنوعی که این پلتفرم پشتیبانی میکند، آزمایشها را انجام دهید:
شبیهسازها، از جمله شبیهساز اندروید و آزمایشگاه تست فایربیس .
تحلیلگر عملکرد ChromeOS ، هنگام اجرای ChromeOS M75 یا بالاتر در دسترس است.