عند توسيع نطاق اللعبة لتشمل أشكال أجهزة مختلفة ذات شاشات كبيرة، يجب مراعاة كيفية تعامل اللعبة مع إدارة النوافذ. على Googlebook وChromeOS وألعاب Google Play على الكمبيوتر، يمكن تشغيل لعبتك في وضع النافذة فوق واجهة سطح المكتب الرئيسية. على أجهزة Android اللوحية والأجهزة القابلة للطي الجديدة التي تعمل بالإصدار 12L من نظام التشغيل Android (المستوى 32 لواجهة برمجة التطبيقات) أو الإصدارات الأحدث التي يبلغ عرض شاشتها 600 وحدة بكسل مستقلة الكثافة أو أكثر، يمكن تشغيل لعبتك جنبًا إلى جنب مع تطبيقات أخرى في وضع تقسيم الشاشة، ويمكن تغيير حجمها، ويمكن حتى نقلها بين الشاشة الداخلية والخارجية على الأجهزة القابلة للطي، ما يؤدي إلى تغيير إعدادات حجم النافذة، وفي بعض الأجهزة، اتجاه الشاشة.
الإعدادات الأساسية للشاشات الكبيرة
حدِّد ما إذا كانت لعبتك متوافقة مع تغيير الحجم:
<android:resizeableActivity="true" or "false" />
إذا تعذّر توفير إمكانية تغيير الحجم، تأكَّد من أنّ بيان اللعبة يحدّد بشكلٍ صريح نِسب العرض إلى الارتفاع الدنيا والقصوى المتوافقة:
<!-- Render full screen between 3:2 and 21:9 aspect ratio -->
<!-- Let the platform letterbox otherwise -->
<activity android:minAspectRatio="1.5">
<activity android:maxAspectRatio="2.33">
ألعاب Google Play على الكمبيوتر
بالنسبة إلى برنامج "ألعاب Google Play على الكمبيوتر"، يتعامل النظام الأساسي مع إمكانية تغيير حجم النافذة مع مراعاة نسبة العرض إلى الارتفاع المحدّدة. يتم تلقائيًا قفل حجم النافذة على الأبعاد المثالية. يجب أن تتوافق اللعبة مع نسبة عرض إلى ارتفاع 16:9 على الأقل إذا كان الاتجاه الأساسي أفقيًا، ومع نسبة عرض إلى ارتفاع 9:16 إذا كانت اللعبة في الوضع العمودي. للحصول على أفضل تجربة، يجب توفير الدعم بشكلٍ واضح لنسب العرض إلى الارتفاع 21:9 و16:10 و3:2 في الألعاب التي يتم تشغيلها في الوضع الأفقي. لا يُشترط إمكانية تغيير حجم النافذة هنا، ولكن من الجيد توفيرها لضمان التوافق مع أشكال الأجهزة الأخرى.
لمزيد من المعلومات وأفضل الممارسات، يُرجى الاطّلاع على مقالة ضبط إعدادات الرسومات في برنامج "ألعاب Google Play على الكمبيوتر".
الشاشات الكبيرة
لزيادة مساحة العرض المتاحة للعبتك في وضع ملء الشاشة على الأجهزة اللوحية ذات الشاشات الكبيرة والأجهزة القابلة للطي وأجهزة Googlebook وChromeOS والشاشات المتصلة، يمكنك إتاحة وضع ملء الشاشة الغامر وإخفاء أشرطة النظام من خلال ضبط العلامات على decorView أو إعدادات إمكانية ظهور واجهة مستخدم النظام أو من خلال واجهة برمجة التطبيقات WindowInsetsCompat. عليك أيضًا التعامل بسلاسة مع أحداث ضبط التدوير وتغيير الحجم أو منع حدوثها.
يُرجى العِلم أنّه على أجهزة Android ذات الشاشات الكبيرة، يمكن تشغيل لعبتك بإعدادات قد لا تكون قد تعاملت معها من قبل. إذا كانت لعبتك لا تتوافق مع جميع إعدادات حجم النافذة والاتجاه، ستضع المنصة لعبتك في إطار وضع التوافق، وستطلب من اللاعب، إذا لزم الأمر، الموافقة قبل التغيير إلى إعداد غير متوافق.
على بعض الأجهزة، عندما ينتقل أحد اللاعبين إلى إعداد غير متوافق، قد يُطلب منه إعادة تحميل اللعبة وإعادة إنشاء النشاط ليتناسب بشكل أفضل مع تخطيط النافذة الجديد، ما يؤدي إلى تعطيل تجربة اللعب. اختبِر لعبتك في إعدادات مختلفة لوضع النوافذ المتعدّدة (حجم النافذة 2/3 أو 1/2 أو 1/3)، وتأكَّد من عدم اقتصاص أي عناصر من أسلوب اللعب أو واجهة المستخدم أو عدم إمكانية الوصول إليها. بالإضافة إلى ذلك، اختبِر طريقة استجابة لعبتك لميزة "استمرارية التطبيق على الأجهزة القابلة للطي" عند الانتقال بين الشاشة الداخلية والخارجية على الأجهزة القابلة للطي. في حال ظهور مشاكل، عليك معالجة أحداث الإعداد هذه بشكل صريح وإضافة ميزة متقدّمة لتغيير حجم الشاشة الكبيرة.
إمكانية تغيير حجم الشاشة المتقدّمة على الأجهزة ذات الشاشات الكبيرة
للخروج من "وضع التوافق" وتجنُّب إعادة إنشاء النشاط، اتّبِع الخطوات التالية:
عليك تعريف نشاطك الرئيسي على أنّه قابل لتغيير الحجم:
<android:resizeableActivity="true" />عليك الإفصاح عن توفير الدعم الصريح لـ "الاتجاه" و"حجم الشاشة" و"أصغر حجم للشاشة" و"تخطيط الشاشة" و "الكثافة" في السمة
android:configChangesلعنصر<activity>في بيان تطبيق لعبتك لتلقّي جميع أحداث إعدادات الشاشة الكبيرة:<android:configChanges="screenSize | smallestScreenSize | screenLayout | orientation | keyboard | keyboardHidden | density" />تجاوز
onConfigurationChanged()والتعامل مع حدث الإعدادات، بما في ذلك الاتجاه الحالي وحجم النافذة والعرض والارتفاع:Kotlin
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() // Configuration.ORIENTATION_PORTRAIT or ORIENTATION_LANDSCAPE val newScreenOrientation: Int = newConfig.orientation // ROTATION_0, ROTATION_90, ROTATION_180, or ROTATION_270 val newScreenRotation: Int = windowManager.defaultDisplay.rotation }
Java
@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); // Configuration.ORIENTATION_PORTRAIT or ORIENTATION_LANDSCAPE int newScreenOrientation = newConfig.orientation; // ROTATION_0, ROTATION_90, ROTATION_180, or ROTATION_270 int newScreenRotation = getWindowManager().getDefaultDisplay() .getRotation(); }
يمكنك أيضًا طلب WindowManager للتحقّق من دوران الجهاز الحالي. باستخدام بيانات التعريف هذه، تحقَّق من أبعاد النافذة الجديدة واعرضها بالحجم الكامل للنافذة. قد لا ينجح ذلك في بعض الحالات بسبب الاختلافات في نسبة العرض إلى الارتفاع، لذا يمكنك بدلاً من ذلك تثبيت واجهة مستخدم اللعبة على حجم النافذة الجديد وإضافة إطار أسود حول محتوى اللعب الأساسي. إذا كانت هناك قيود فنية أو متعلّقة بالتصميم تمنع اتّباع أيّ من الطريقتَين، يمكنك إنشاء تأثير letterbox داخل المحرّك للحفاظ على نسبة العرض إلى الارتفاع، وتغيير الحجم إلى أفضل الأبعاد الممكنة مع تحديد resizeableActivity = false وتجنُّب وضع الإعداد.
بغض النظر عن الأسلوب الذي تتّبعه، عليك اختبار لعبتك في إعدادات مختلفة (الطي والفتح، وتغييرات مختلفة في اتجاه الشاشة، ووضع تقسيم الشاشة) والتأكّد من عدم حدوث أي قطع أو تداخل في عناصر واجهة المستخدم داخل اللعبة، أو مشاكل في إمكانية الوصول إلى عناصر اللمس، أو مشاكل في نسبة العرض إلى الارتفاع تؤدي إلى تمديد اللعبة أو ضغطها أو تشويهها بأي شكل آخر.
بالإضافة إلى ذلك، تعني الشاشات الأكبر عادةً وحدات بكسل أكبر، لأنّ عدد وحدات البكسل يكون هو نفسه في مساحة أكبر بكثير. يمكن أن يؤدي ذلك إلى تشوّش في وحدات تخزين العرض التي تم تصغيرها أو مواد العرض ذات الدقة المنخفضة. استخدِم مواد العرض الأعلى جودة على الأجهزة ذات الشاشات الكبيرة وحدِّد ملف أداء لعبتك للتأكّد من عدم حدوث أي مشاكل. إذا كانت لعبتك تتوافق مع مستويات جودة متعددة، تأكَّد من أنّها تراعي الأجهزة ذات الشاشات الكبيرة.
وضع النوافذ المتعددة
يتيح وضع النوافذ المتعددة لتطبيقات متعددة مشاركة الشاشة نفسها في الوقت نفسه. لا يغيّر وضع النوافذ المتعدّدة دورة حياة النشاط، ولكن تختلف حالة الاستئناف للتطبيقات في النوافذ المتعدّدة باختلاف إصدارات Android (راجِع دورة حياة النشاط في وضع النوافذ المتعدّدة ضمن إتاحة وضع النوافذ المتعدّدة).
عندما يضع اللاعب تطبيقًا أو لعبة في وضع النوافذ المتعددة، يُعلم النظام النشاط بتغيير في الإعدادات على النحو المحدّد في قسم إمكانية تغيير الحجم المتقدّمة على الشاشات الكبيرة. يحدث تغيير في الإعدادات أيضًا عندما يغيّر اللاعب حجم اللعبة أو يعيدها إلى وضع ملء الشاشة.
لا نضمن أن يستعيد التطبيق التركيز عند وضعه في وضع النوافذ المتعددة. لذلك، إذا كنت تستخدم أيًا من أحداث حالة التطبيق لإيقاف لعبتك مؤقتًا، لا تعتمد على حدث اكتساب التركيز (onWindowFocusChanged() مع قيمة التركيز على أنّها صحيحة) لاستئناف اللعبة. بدلاً من ذلك، استخدِم معالجات الأحداث الأخرى أو معالجات تغيير الحالة، مثل onConfigurationChanged() أو onResume(). يُرجى العِلم أنّه يمكنك دائمًا استخدام طريقة isInMultiWindowMode() لمعرفة ما إذا كان النشاط الحالي يعمل في وضع النوافذ المتعددة.
عند استخدام ميزة "العرض في نافذة" على أجهزة Googlebook وChromeOS والأجهزة اللوحية ذات الشاشات الكبيرة والأجهزة القابلة للطي، تصبح أبعاد النافذة الأولية من الاعتبارات المهمة. لا يجب أن تكون اللعبة بملء الشاشة، وعليك تحديد حجم النافذة في هذه الحالة. هناك طريقتان مقترَحتان للتعامل مع هذه المشكلة.
يعمل الخيار الأول من خلال استخدام سمات معيّنة في العلامة <layout> في ملف البيان الخاص بتطبيق Android. تتحكّم السمتان defaultHeight وdefaultWidth في الأبعاد الأولية. يجب أيضًا الانتباه إلى السمتَين minHeight وminWidth لمنع اللاعبين من تغيير حجم نافذة اللعبة إلى أبعاد لا تتوافق معها. أخيرًا، هناك السمة gravity التي تحدّد موضع ظهور النافذة على الشاشة عند تشغيلها. في ما يلي مثال على علامة تخطيط تستخدم هذه السمات:
<layout android:defaultHeight="500dp"
android:defaultWidth="600dp"
android:gravity="top|end"
android:minHeight="450dp"
android:minWidth="300dp" />
يعمل الخيار الثاني لضبط حجم النافذة من خلال استخدام حدود التشغيل الديناميكية. باستخدام setLaunchBounds(Rect)، يمكنك تحديد أبعاد النافذة الأولية. في حال تحديد مستطيل فارغ، يتم بدء النشاط في حالة مكبّرة.
بالإضافة إلى ذلك، إذا كنت تستخدم محرّكَي الألعاب Unity أو Unreal، تأكَّد من استخدام إصدار حديث (Unity 2019.4.40 وUnreal 5.3 أو إصدار أحدث) يوفّر توافقًا جيدًا مع وضع النوافذ المتعددة.
دعم وضعية الهاتف القابل للطي
استخدِم مكتبة تخطيط WindowManager من Jetpack لتوفير أوضاع الأجهزة القابلة للطي، مثل وضع الطاولة، من أجل زيادة انغماس اللاعبين وتفاعلهم:
Kotlin
fun isTableTopPosture(foldFeature : FoldingFeature?) : Boolean { contract { returns(true) implies (foldFeature != null) } return foldFeature?.state == FoldingFeature.State.HALF_OPENED && foldFeature.orientation == FoldingFeature.Orientation.HORIZONTAL }
Java
boolean isTableTopPosture(FoldingFeature foldFeature) { return (foldFeature != null) && (foldFeature.getState() == FoldingFeature.State.HALF_OPENED) && (foldFeature.getOrientation() == FoldingFeature.Orientation.HORIZONTAL); }