Prendre en charge le redimensionnement des grands écrans

En passant des téléphones à différents facteurs de forme pour grands écrans, vous devez tenir compte de la façon dont votre jeu gère les fenêtres. Sous ChromeOS et Google Play Jeux sur PC, votre jeu peut s'exécuter en mode fenêtre sur une interface de bureau principale. Sur les nouvelles tablettes et appareils pliables Android équipés d'Android 12L (niveau d'API 32) ou version ultérieure avec une largeur d'écran supérieure à 600 dp, votre jeu peut s'exécuter côte à côte en mode Écran partagé avec d'autres applications, être redimensionnés et même être déplacés entre l'écran intérieur et l'écran extérieur sur les appareils pliables, ce qui entraîne une modification de la configuration pour la taille de la fenêtre et, sur certains appareils, l'orientation.

Configuration de base pour les grands écrans

Indiquez si votre jeu est redimensionnable:

<android:resizeableActivity="true" or "false" />

Si aucun redimensionnement ne peut être effectué, assurez-vous que le fichier manifeste du jeu définit explicitement les formats minimal et maximal compatibles:

<!-- 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 Jeux sur PC

Pour Google Play Jeux sur PC, la plate-forme gère le redimensionnement de la fenêtre tout en respectant le format spécifié. La taille de la fenêtre est automatiquement verrouillée sur les dimensions optimales. Votre jeu doit être compatible avec le format 16:9 si votre orientation principale est le mode paysage et le format 9:16 si votre jeu est en mode portrait. Pour une expérience optimale, veillez à ce que les formats 21:9, 16:10 et 3:2 soient explicitement acceptés dans les jeux en mode paysage. Le redimensionnement de la fenêtre n'est pas nécessaire ici, mais il est utile pour la compatibilité avec d'autres facteurs de forme.

Pour en savoir plus et découvrir les bonnes pratiques, consultez Configurer les éléments graphiques pour Google Play Jeux sur PC.

Grands écrans ChromeOS et Android

Pour maximiser la zone d'affichage de votre jeu en plein écran sur ChromeOS et les appareils Android à grand écran, assurez-vous d'accepter le mode immersif plein écran et masquez les barres système en définissant des indicateurs sur decorView, la visibilité de l'UI du système ou via l'API WindowInsetsCompat. Vous devez également gérer de façon optimale les événements de rotation et de redimensionnement de la configuration, ou empêcher qu'ils se produisent sur les appareils ChromeOS.

Notez que sur les appareils Android à grand écran, votre jeu peut s'exécuter dans des configurations que vous ne gérez peut-être pas déjà. Si votre jeu n'est pas compatible avec toutes les configurations de taille et d'orientation de fenêtre, la plate-forme l'affiche au format letterbox en mode de compatibilité et, si nécessaire, invite le joueur avant de passer à une configuration non compatible.

Figure 1 : Boîte de dialogue de compatibilité de la configuration.

Sur certains appareils, lorsqu'un joueur passe à une configuration non compatible, il peut être invité à actualiser le jeu et à recréer l'activité pour qu'elle s'adapte au mieux à la nouvelle mise en page, ce qui perturbe l'expérience de jeu. Testez votre jeu dans différentes configurations en mode multifenêtre (taille de fenêtre 2/3, 1/2 et 1/3), et vérifiez qu'aucun élément du jeu ou de l'interface utilisateur n'est tronqué ni inaccessible. De plus, testez la façon dont votre jeu réagit à la continuité des écrans pliables lorsque vous passez de l'écran intérieur à l'écran extérieur sur des appareils pliables. Si vous rencontrez des problèmes, gérez explicitement ces événements de configuration et ajoutez une fonctionnalité avancée de redimensionnement sur grand écran.

Redimensionnement avancé sur grand écran

Figure 2 : Différentes interfaces utilisateur sur ordinateur et appareil pliable en position à plat.

Pour quitter le mode de compatibilité et éviter la recréation d'activité, procédez comme suit:

  1. Déclarez votre activité principale comme redimensionnable:

    <android:resizeableActivity="true" />
    
  2. Déclarez explicitement la prise en charge des éléments "orientation", "screenSize", "smallestScreenSize", "screenLayout" et "densité" dans l'attribut android:configChanges de l'élément <activity> du fichier manifeste de votre jeu pour recevoir tous les événements de configuration pour les grands écrans:

    <android:configChanges="screenSize | smallestScreenSize | screenLayout | orientation | keyboard |
                            keyboardHidden | density" />
    
  3. Ignorez onConfigurationChanged() et gérez l'événement de configuration, y compris l'orientation, la taille de la fenêtre, la largeur et la hauteur actuelles:

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

Vous pouvez également interroger WindowManager pour vérifier la rotation actuelle de l'appareil. À l'aide de ces métadonnées, vérifiez les nouvelles dimensions de fenêtre et affichez la fenêtre en plein écran. Cela peut ne pas fonctionner dans tous les cas en raison des différences de format. Vous pouvez donc également ancrer l'UI de votre jeu sur la nouvelle taille de la fenêtre et utiliser le format letterbox pour le contenu principal de votre jeu. Si des limites techniques ou de conception vous empêchent d'utiliser l'une ou l'autre de ces approches, créez votre propre format letterbox dans le moteur pour conserver le format, puis adaptez-la aux meilleures dimensions possible tout en déclarant resizeableActivity = false et en évitant le mode de configuration.

Quelle que soit l'approche que vous adoptez, testez votre jeu dans différentes configurations (plier et déplier, différents changements de rotation, mode Écran partagé) et assurez-vous qu'il n'y a pas d'éléments d'interface utilisateur tronqués ou qui se chevauchent, de problèmes d'accessibilité des zones cibles tactiles ou de problèmes de format pouvant entraîner l'étirement, l'écrasement ou la déformation du jeu.

De plus, les écrans plus grands signifient généralement les pixels plus grands, car vous avez le même nombre de pixels pour une zone beaucoup plus grande. Cela peut entraîner une pixellisation des tampons de rendu réduits ou des éléments de résolution inférieure. Utilisez vos assets de la plus haute qualité sur les appareils à grand écran et profilez les performances de votre jeu pour vous assurer qu'il ne présente aucun problème. Si votre jeu est compatible avec plusieurs niveaux de qualité, assurez-vous qu'il est adapté aux appareils à grand écran.

Mode multifenêtre

Le mode multifenêtre permet à plusieurs applications de partager simultanément le même écran. Le mode multifenêtre ne modifie pas le cycle de vie d'une activité. Toutefois, l'état de reprise des applications dans plusieurs fenêtres varie selon les versions d'Android (consultez Cycle de vie d'une activité en mode multifenêtre dans Compatibilité avec le mode multifenêtre).

Lorsque le joueur active une application ou un jeu en mode multifenêtre, le système avertit l'activité d'un changement de configuration, comme spécifié dans la section Redimensionnement avancé sur les grands écrans. Un changement de configuration se produit également lorsque le joueur redimensionne le jeu ou le remet en mode plein écran.

Rien ne garantit que l'application redeviendra active lorsqu'elle passera en mode multifenêtre. Par conséquent, si vous utilisez l'un des événements d'état de l'application pour mettre en pause votre jeu, ne comptez pas sur l'événement d'acquisition de focus (onWindowFocusChanged() avec la valeur de focus sur "true") pour reprendre le jeu. Utilisez plutôt d'autres gestionnaires d'événements ou gestionnaires de changement d'état tels que onConfigurationChanged() ou onResume(). Notez que vous pouvez toujours utiliser la méthode isInMultiWindowMode() pour détecter si l'activité en cours est exécutée en mode multifenêtre.

Avec le mode multifenêtre sur ChromeOS, les dimensions initiales de la fenêtre sont importantes. Il n'est pas nécessaire qu'un jeu s'affiche en plein écran. Dans ce cas, vous devez déclarer la taille de la fenêtre. Deux méthodes sont recommandées.

La première consiste à utiliser des attributs spécifiques au niveau de la balise <layout> dans votre fichier manifeste Android. Les attributs defaultHeight et defaultWidth contrôlent les dimensions initiales. Prenez également en compte les attributs minHeight et minWidth pour éviter que les joueurs ne redimensionnent la fenêtre du jeu en dimensions que vous n'acceptez pas. Enfin, l'attribut gravity détermine l'emplacement de la fenêtre à l'écran lorsqu'elle est lancée. Voici un exemple de balise de mise en page utilisant ces attributs:

<layout android:defaultHeight="500dp"
        android:defaultWidth="600dp"
        android:gravity="top|end"
        android:minHeight="450dp"
        android:minWidth="300dp" />

La deuxième option de définition de la taille de la fenêtre repose sur l'utilisation de limites de lancement dynamiques. En utilisant setLaunchBounds(Rect)⁠⁠, vous pouvez définir les dimensions de la fenêtre de départ. Si un rectangle vide est spécifié, l'activité est démarrée dans un état maximisé.

En outre, si vous utilisez les moteurs de jeu Unity ou Unreal, assurez-vous d'utiliser une version récente (Unity 2019.4.40 et Unreal 5.3 ou version ultérieure) compatible avec le mode multifenêtre.

Compatibilité avec les appareils pliables

Utilisez la bibliothèque de mises en page WindowManager de Jetpack pour prendre en charge les positions des appareils pliables, par exemple à plat, afin d'améliorer l'immersion et l'engagement du joueur:

Figure 3 : Jeu en position à plat avec la vue principale sur la partie verticale de l'écran et les commandes sur la partie horizontale.

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