عند التوسّع من الهواتف إلى أشكال الأجهزة ذات الشاشات الكبيرة المختلفة، يتطلب ذلك اعتبارات حول كيفية تعامل لعبتك مع إدارة النوافذ. على نظامَي التشغيل ChromeOS وألعاب Google Play على الكمبيوتر، يمكن تشغيل لعبتك في وضع النافذة على واجهة كمبيوتر مكتبي رئيسية. على الأجهزة اللوحية والأجهزة القابلة للطي الجديدة التي تعمل بنظام التشغيل Android التي تعمل بنظام التشغيل Android 12L (المستوى 32 لواجهة برمجة التطبيقات) أو الإصدارات الأحدث مع عرض الشاشة > 600 بكسل مستقل الكثافة، يمكن تشغيل لعبتك جنبًا إلى جنب في وضع الشاشة المقسَّمة مع التطبيقات الأخرى، ويمكن تغيير حجمها أو نقلها بين الشاشة الداخلية والخارجية على الأجهزة القابلة للطي، ما يؤدي إلى تغيير إعدادات حجم النافذة والاتجاه في بعض الأجهزة.
قابلية تنفيذ المهام من خلال ألعاب Unity
الإعداد الأساسي للشاشة الكبيرة
عليك توضيح ما إذا كانت لعبتك قادرة على التعامل مع إمكانية إعادة التعديل:
<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 على الكمبيوتر".
الشاشات الكبيرة لنظام التشغيل ChromeOS وAndroid
لزيادة مساحة العرض للعبتك في وضع ملء الشاشة على ChromeOS وأجهزة Android ذات الشاشات الكبيرة، يمكنك إتاحة وضع العرض المجسم بملء الشاشة وإخفاء أشرطة النظام من خلال وضع علامات على decorView
أو ظهور واجهة مستخدم النظام أو من خلال WindowInsetsCompat
API. ستحتاج أيضًا إلى التعامل مع أحداث الضبط وتغيير حجم تغييرات الدوران بسلاسة أو منع حدوثها على أجهزة ChromeOS.
يُرجى ملاحظة أنّه على أجهزة Android ذات الشاشات الكبيرة، يمكن تشغيل لعبتك بإعدادات قد لا يكون بإمكانك ضبطها حاليًا. إذا كانت لعبتك لا تتوافق مع كل إعدادات حجم النافذة والاتجاه، ستعرِض المنصة لعبتك في وضع التوافق لتطلب من اللاعب قبل التغيير إلى إعداد غير متوافق إذا لزم الأمر، إذا لزم الأمر.
على بعض الأجهزة، عندما ينتقل اللاعب إلى إعدادات غير متوافقة، قد يظهر له خيار إعادة تحميل اللعبة وإعادة إنشاء النشاط ليتناسب بشكل أفضل مع تصميم النافذة الجديد، ما يتأثّر تجربة اللعب. اختبِر لعبتك من خلال إعدادات مختلفة لوضع النوافذ المتعددة (2/3 و1/2 و1/3 من حجم النافذة) وتحقَّق من عدم اقتطاع عناصر اللعب أو واجهة المستخدم أو تعذّر الوصول إليها. بالإضافة إلى ذلك، يمكنك اختبار استجابة لعبتك لحركة البيانات القابلة للطيّ عند التنقّل بين الشاشة الداخلية والخارجية على الأجهزة القابلة للطي. إذا ظهرت لك مشاكل، عليك التعامل مع أحداث الضبط هذه بشكل صريح وإضافة دعم متقدِّم لتغيير إمكانية تغيير الشاشة الكبيرة.
إمكانية تغيير حجم الشاشة الكبيرة بشكل متقدِّم
للخروج من وضع التوافق وتجنُّب إعادة إنشاء الأنشطة، عليك إجراء ما يلي:
تحديد نشاطك الرئيسي على أنّه قابل لتغيير الحجم:
<android:resizeableActivity="true" />
توضيح الدعم الصريح لـ "orientation" (الاتجاه) و"screenSize" و"smallestscreenSize" و"screenLayout" و"الكثافة" في السمة
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
للاطّلاع على دوران الجهاز الحالي. باستخدام هذه البيانات الوصفية، يمكنك التحقّق من أبعاد النافذة الجديدة وعرضها بحجم النافذة الكامل. قد لا ينجح ذلك في جميع الحالات بسبب الاختلافات في نسبة العرض إلى الارتفاع، لذا عليك بدلاً من ذلك تثبيت واجهة مستخدم لعبتك مع حجم النافذة الجديد وضبط محتوى أسلوب اللعب الأساسي المُعدّ للعرض على شاشة عريضة أفقيًا. إذا كانت هناك قيود فنية أو قيود على التصميم تمنع استخدام أيٍّ من الطريقتَين، يمكنك إعداد مكوّنات رقمية داخل المحرك داخل المحرّك للحفاظ على نسبة العرض إلى الارتفاع، وتعديل الحجم وفقًا لأفضل الأبعاد الممكنة مع تعريف السمة resizeableActivity = false
وتجنُّب وضع الضبط.
بغض النظر عن النهج الذي تتّبعه، اختبِر لعبتك بتكوينات مختلفة (الطيّ والفتح والتغييرات المختلفة في الدوران ووضع تقسيم الشاشة) والتأكّد من عدم وجود أجزاء أو تداخل في واجهة المستخدم داخل اللعبة، أو عدم حدوث مشاكل في إمكانية الوصول إلى الأهداف التي تستهدف اللمس، أو مشاكل في نسبة العرض إلى الارتفاع تؤدي إلى تمديد اللعبة أو انضغاطها أو تشويهها بأي شكل آخر.
بالإضافة إلى ذلك، عادةً ما تعني الشاشات الأكبر بكسلات أكبر، لأن لديك نفس عدد البكسل لمساحة أكبر بكثير. وقد يؤدي ذلك إلى حدوث تقطيع في المخازن المؤقتة للعرض أو مواد العرض ذات الدقة المنخفضة. استخدِم مواد العرض الأعلى جودة على الأجهزة ذات الشاشات الكبيرة والملف الشخصي للأداء للعبتك لضمان عدم حدوث أي مشاكل. إذا كانت لعبتك متوافقة مع مستويات جودة متعدّدة، تأكَّد من أنّها تناسب الأجهزة ذات الشاشات الكبيرة.
وضع النوافذ المتعددة
يتيح وضع النوافذ المتعددة لتطبيقات متعددة مشاركة الشاشة نفسها في آنٍ واحد. لا يؤدي وضع النوافذ المتعددة إلى تغيير دورة حياة النشاط، ومع ذلك، تختلف حالة استئناف التطبيقات في نوافذ متعددة على الإصدارات المختلفة من Android (راجِع دورة حياة النشاط في وضع النوافذ المتعددة في إتاحة وضع النوافذ المتعددة).
عندما يضع اللاعب تطبيقًا أو لعبة في وضع النوافذ المتعددة، يرسل النظام إشعارًا إلى حدوث تغيير في الإعدادات كما هو محدد في قسم إمكانية تغيير حجم الشاشة الكبيرة المتقدمة. يحدث تغيير في الإعدادات أيضًا عندما يغيّر اللاعب حجم اللعبة أو يُعيد تشغيل اللعبة في وضع ملء الشاشة.
وليس هناك ما يضمن إعادة تركيز التطبيق عند تفعيل وضع النوافذ المتعددة. وبالتالي، إذا استخدمت أيًا من أحداث حالة التطبيق لإيقاف لعبتك مؤقتًا، لا تعتمد على حدث التركيز الذي تم اكتسابه (onWindowFocusChanged()
مع ضبط قيمة التركيز على "صحيح") لاستئناف اللعبة. بدلاً من ذلك، استخدِم معالِجات أخرى للأحداث أو معالِجات تغيير الحالة، مثل onConfigurationChanged()
أو onResume()
. تجدر الإشارة إلى أنّه يمكنك دائمًا استخدام طريقة isInMultiWindowMode()
لرصد ما إذا كان النشاط الحالي يعمل في وضع النوافذ المتعددة.
في حال استخدام وضع النوافذ المتعددة في 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); }