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

عند التوسّع من الهواتف إلى أشكال الأجهزة ذات الشاشات الكبيرة المختلفة، يتطلب ذلك اعتبارات حول كيفية تعامل لعبتك مع إدارة النوافذ. على نظامَي التشغيل ChromeOS وبرنامج "ألعاب Google Play على الكمبيوتر"، يمكن تشغيل لعبتك في وضع النافذة على واجهة كمبيوتر مكتبي رئيسية. على أجهزة Android اللوحية والأجهزة القابلة للطي الجديدة التي تعمل بالإصدار 12L من نظام التشغيل Android (المستوى 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. ستحتاج أيضًا إلى التعامل مع أحداث الضبط وتغيير حجم تغييرات الدوران بسلاسة أو منع حدوثها على أجهزة ChromeOS.

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

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

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

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

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

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

  1. تحديد نشاطك الرئيسي على أنّه قابل لتغيير الحجم:

    <android:resizeableActivity="true" />
    
  2. يُرجى تقديم بيان عن التوافق الصريح لـ "الاتجاه" و"حجم الشاشة" و"أصغر حجم شاشة" و"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);
}