دعم إمكانية تغيير حجم الشاشة الكبيرة

عند توسيع نطاق استخدام الهاتف واستخدام أشكال الأجهزة ذات الشاشات الكبيرة، يجب مراعاة كيفية تعامل لعبتك مع إدارة النوافذ. على نظامَي التشغيل 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 على الكمبيوتر".

شاشات كبيرة بنظام التشغيل ChromeOS وAndroid

لزيادة مساحة إمكانية عرض لعبتك في وضع ملء الشاشة على ChromeOS وأجهزة Android ذات الشاشات الكبيرة، يمكنك إتاحة الوضع المجسم بملء الشاشة وإخفاء أشرطة النظام من خلال وضع علامات على decorView أو مستوى ظهور واجهة مستخدم النظام أو من خلال واجهة برمجة التطبيقات WindowInsetsCompat. ستحتاج أيضًا إلى التعامل بسلاسة مع أحداث الضبط وتغيير حجمها أو منع حدوثها على أجهزة ChromeOS.

تجدر الإشارة إلى أنّه على أجهزة Android ذات الشاشات الكبيرة، يمكن تشغيل لعبتك بإعدادات قد لا تعرفها بعد. إذا كانت لعبتك لا تتوافق مع جميع إعدادات حجم النافذة واتجاهها، فإنّ النظام الأساسي يعرض لعبتك في وضع التوافق، ويُظهر عند الضرورة اللاعب قبل التبديل إلى إعداد غير متوافق.

الشكل 1. مربّع حوار لتوافق الإعدادات

في بعض الأجهزة، عندما ينتقل اللاعب إلى إعدادات غير متوافقة، قد يُطلب منه خيار إعادة تحميل اللعبة وإعادة إنشاء النشاط بما يتناسب على أفضل نحو مع تنسيق النافذة الجديد، ما يتسبّب في إيقاف تجربة اللعب. اختبِر لعبتك باستخدام إعدادات متنوعة لوضع النوافذ المتعددة (2/3 أو 1/2 أو 1/3 لحجم النافذة) وتأكَّد من عدم اقتصاص أي عناصر أسلوب اللعب أو واجهة المستخدم أو تعذُّر الوصول إليها. بالإضافة إلى ذلك، يمكنك اختبار مدى استجابة لعبتك لمتعة الألعاب القابلة للطي عند التنقّل بين الشاشة الداخلية والخارجية على الأجهزة القابلة للطي. في حال ظهور مشاكل، عليك معالجة أحداث الضبط هذه بشكل صريح وإضافة الدعم المتقدّم والمتقدم لتغيير حجم الشاشات الكبيرة.

قابلية متقدّمة لتغيير حجم الشاشة الكبيرة

الشكل 2. واجهات مستخدم مختلفة على سطح المكتب وقابلة للطي في وضع "التثبيت على سطح مستوٍ".

للخروج من وضع التوافق وتجنُّب إعادة إنشاء النشاط، عليك تنفيذ ما يلي:

  1. وضِّح أنّ نشاطك الرئيسي يمكن تغيير حجمه:

    <android:resizeableActivity="true" />
    
  2. يجب توضيح الدعم الصريح لـ "orientation" و"screenSize" و"smallestScreenSize" و"screenLayout" و "الكثافة" في السمة android:configChanges للعنصر <activity> في بيان اللعبة لتلقّي جميع أحداث ضبط الشاشة الكبيرة:

    <android:configChanges="screenSize | smallestScreenSize | screenLayout | orientation | keyboard |
                            keyboardHidden | density" />
    
  3. يمكنك إلغاء 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 لإتاحة أوضاع الشاشة القابلة للطي، مثل الوضع "التثبيت على سطح مستوٍ"، لزيادة تفاعل اللاعبين وزيادة تفاعلهم:

الشكل 3. اللعبة في وضع "التثبيت على سطح مستوٍ" مع وضع العرض الرئيسي على الشاشة العمودية، وعناصر التحكّم في الجزء الأفقي.

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);
}