Adapter le jeu Android à différentes tailles d'écran


11

Je crée un jeu Android uniquement en orientation écran portrait. Cela fonctionne très bien lorsque je l'exécute sur mon téléphone, mais lorsque je l'exécute sur une tablette, même si la taille de l'écran est plus grande, tous les bitmaps sont de la même taille. Existe-t-il un moyen de faire en sorte que les bitmaps restent dans la même proportion, même sur des écrans de tailles différentes?

Réponses:


11

À moins que vous n'utilisiez AbsoluteLayout (généralement une très mauvaise idée, car vous concevez votre mise en page en utilisant les coordonnées x / y, qui ne conviendront qu'à l'appareil sur lequel il a été conçu), cela ne devrait pas se produire - les applications Android s'ajustent automatiquement à la taille de l'écran de l'appareil . Cependant, d'après ce que vous décrivez (la disposition ne s'ajuste pas à l'écran du tableau), il semble que AbsoluteLayout soit le problème ici.

Assurez-vous que dans vos fichiers XML de mise en page, vous N'utilisez PAS de mises en page absolues (cela inclut la définition de coordonnées / largeurs / hauteurs explicites sur tout type de vue). Envisagez plutôt d'utiliser:

  • LinearLayout - Empile plusieurs vues horizontalement ou verticalement
  • FrameLayout - contient généralement un enfant
  • RelativeLayout - Alignez les enfants les uns par rapport aux autres
  • TableLayout - Une disposition basée sur un tableau
  • ScrollView - Peut contenir un élément enfant (tel qu'un LinearLayout) et vous permet de faire défiler son contenu

... tout ce qui convient le mieux à votre objectif.

Si vous êtes nouveau sur Android , Google propose un joli didacticiel qui présente les différents types de mise en page mentionnés ci-dessus. Plus de tutoriels peuvent être trouvés ici .

De plus, votre niveau API serait pertinent (pour savoir si vous utilisez Android 2.x ou 4.x - je ne suppose pas 3.x car il n'est pas disponible pour les smartphones) pour déterminer la cause de votre problème.

Forcer votre application en mode Portrait en définissant:

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    // Set screen orientation for this dialog to portrait
    setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT);
}

... dans votre Activité qui affiche les vues du jeu?

Veuillez fournir plus d'informations sur la façon dont vous mettez en page vos vues (utilisez-vous XML pour la mise en page que vous gonflez plus tard dans votre activité, ou utilisez-vous la mise en page dans le code dans votre activité, etc.)? De plus: avez-vous essayé d'exécuter votre application dans un émulateur de type smartphone et tablette? Si oui, le problème persiste-t-il?


MISE À JOUR: COMMENT METTRE À L'ÉCHELLE LES BITMAPS

L'OP a demandé comment il peut mettre à l'échelle le bitmap qu'il utilise dans son jeu. Une option (de tout ce que je sais sur la configuration de l'OP): Le SurfaceHolder.Callback que vous remplacez pour afficher votre jeu et sur lequel vous restituez tous les Bitmaps, etc. a une méthode appelée:

surfaceChanged(SurfaceHolder holder, int format, int width, int height)

Cette méthode vous donne la largeur / hauteur de votre surface, vous pouvez donc maintenant utiliser:

Bitmap.createScaledBitmap (Bitmap src, int dstWidth, int dstHeight, boolean filter)

à partir de la classe Bitmap . Pour redimensionner vos images proportionnellement à la taille de la surface sur laquelle vous dessinez.

Ce que vous devez faire est le suivant: si vous connaissez les dimensions de votre bitmap par rapport à une taille d'écran donnée, par exemple la taille d'écran de votre smartphone. Ensuite, vous pouvez calculer les dimensions cibles des bitmaps mis à l'échelle. Voici les mathématiques (enveloppées dans un exemple):

Supposons que vous ayez un bitmap A aux dimensions 25x50 (largeurxhauteur) qui s'affiche sur un écran aux dimensions 100x200 (largeurxhauteur). Pour cette taille d'écran (100x200), le bitmap a les bonnes dimensions - maintenant, si vous voulez afficher le bitmap sur un écran plus grand, vous devez:

  • Calculer le facteur d'échelle pour la taille du bitmap
  • Conserver le rapport hauteur / largeur du bitmap (afin qu'il ne soit pas déformé)

Supposons que l'écran plus grand mesure 200 x 300 (largeur x hauteur), puis le facteur d'échelle pour la largeur est:

200(target screen width)/100(default screen width) = 2

Donc, 2 est notre facteur d'échelle pour la valeur de largeur et de hauteur du bitmap, car nous devons maintenir le rapport d'aspect du bitmap, nous pouvons simplement multiplier le facteur d'échelle par la largeur et la hauteur du bitmap:

bitmapWidth * 2 = scaledBitmapWidth
bitmapHeight * 2 = scaledBitmapHeight

Donc, en utilisant notre exemple de bitmap A ci-dessus et la formule mentionnée, les nouvelles dimensions du bitmap seraient: 50x100 (widthxheight) parce que:

 2*25(width) = 50 height
 2*50(height) = 100 height

Alors maintenant que nous connaissons la nouvelle taille de notre bitmap, nous utilisons simplement l'appel API que j'ai mentionné ci-dessus et remplissons les blancs:

   Bitmap.createScaledBitmap (myBitmap, 50, 100, false)

myBitmap dans l'exemple ci-dessus est le bitmap A d'origine qui avait les dimensions 25x50 et est mis à l'échelle à 50x100 en utilisant l'extrait de code ci-dessus.


Cependant - cela ne résoudrait pas votre problème d'origine de l'application ne prenant que le coin supérieur droit d'un appareil de la taille d'une tablette. Pour répondre à cette question, nous aurions besoin de réponses aux questions que nous vous avons posées concernant votre configuration. Je vais les résumer rapidement ici:

  • Utilisez-vous un moteur de jeu comme AndEngine ou Unity ?
  • Ecrivez-vous votre mise en page en xml? Si oui, quelle est votre configuration racine pour rendre le contenu de votre jeu?
  • Vous avez mentionné que vous implémentez SurfaceHolder.Callback? La largeur / hauteur fournie dans l'appel de méthode de surfaceChanged vous donne la taille de la surface - est-ce la même taille lorsque votre application s'exécute sur un smartphone ou une tablette?
  • Avez-vous un accès à SurfaceView (ou à tout ce qui est lié à ce SurfaceHolder.Callback que vous implémentez), afin que nous puissions déterminer si c'est celui qui définit de manière rigide la taille de l'application à la taille du smartphone.
  • Les mêmes problèmes de redimensionnement se produisent-ils dans l'émulateur avec différentes résolutions d'écran?

Une suspicion générale: tous les smartphones n'ont pas la même taille d'écran, en fait, il existe une large gamme de tailles d'écran, ce qui me fait me demander: avez-vous déjà testé votre application sur un smartphone avec une taille d'écran différente de celle de votre écran? Parce que - le fait qu'il s'adapte à votre écran, mais pas à une tablette, me fait me demander qui définit ces dimensions et quand. Parce que je doute qu'une application puisse s'adapter à toutes les tailles d'écran de smartphone, mais pas aux tailles de tablette - cela n'aura pas beaucoup de sens (car elles ont plus ou moins le même noyau Android sur elles, quelques différences entre sx, 3. x et 4.x mis à part) À MOINS que vous n'utilisiez un cadre qui ne prend pas en charge (pour une raison quelconque - vous devrez peut-être acheter un support de tablette supplémentaire ou autre) pour les tailles d'écran de la taille d'une tablette. C'est pourquoi il est très important de savoir si l'application se redimensionne correctement uniquement sur votre téléphone, ou sur d'autres smartphones également. La seule façon dont je sais comment une application peut être limitée à la taille d'écran d'un téléphone spécifique est d'utiliser AbsoluteLayout et les dimensions généralement absolues des widgets, etc.


MISE À JOUR: Mise à l'échelle des coordonnées x / y

Afin d'ajuster l'emplacement de votre bitmap à la taille de l'écran, quelque chose comme ce qui suit devrait faire le travail:

  • Dimensions écran: 100/200 (largeur / hauteur)
  • Emplacement du bitmap: x = 50 / y = 100

Maintenant, si vous augmentez la taille de l'écran, vous devrez mettre à l'échelle ces valeurs x / y le long:

  • Dimensions écran: 200/400 (largeur / hauteur)

Le facteur d'échelle serait de 2, car la largeur et la hauteur ont également augmenté de deux. D'où les dimensions seraient ...

  • Emplacement du bitmap: x = 100 / y = 200

Un autre essai - cette fois avec différents facteurs d'échelle pour la largeur / hauteur

  • Dimensions de l'écran: 100/150 (largeur / hauteur)
  • Emplacement du bitmap: x = 50 / y = 50

Si le nouvel écran cible est 150/250, les calculs sont les suivants:

  • Facteur d'échelle pour la largeur = largeur cible / largeur d'origine = 1,5
  • Facteur d'échelle pour la hauteur = targetHeight / originalHeight = 1.666 ... (Period)

Maintenant, nous devons mettre à l'échelle les coordonnées x / y, x est mis à l'échelle en utilisant l'échelle de largeur et la hauteur est mise à l'échelle en utilisant l'échelle de hauteur, voici le résultat:

  • x = original X * 1,5 = 75
  • y = originalY * 1.666 .. (Période) = 83.333 ... (Période)

Ainsi, les nouvelles dimensions de l'écran et les coordonnées x / y mises à l'échelle sont:

  • largeur = 150
  • hauteur = 250
  • x = 75
  • y = 83 333 ... (période)

Pour faire court, l'algorithme de mise à l'échelle des bitmaps est le suivant:

X = (targetScreenWidth / defaultScreenWidth) * defaultXCoordinate
Y = (targetScreenHeight / defaultScreenHeight) * defaultYCoordinate

Mon jeu utilise un panneau de jeu qui étend SurfaceHolder.Callback (il se trouve dans un fichier XML appelé par une activité). Cela pourrait-il faire partie du problème?
user1404512

@ user1404512 Un SurfaceHolder.Callback est généralement lié à une SurfaceView - et cela dépend également de la façon dont cette SurfaceView est configurée (largeur / hauteur) si elle est incorporée dans une autre mise en page (comme FrameLayout etc.) ... dans votre A SurfaceHolder.Callback là-bas devrait être une méthode: public void surfaceChanged (support SurfaceHolder, format int, largeur int, hauteur int) la largeur et la hauteur devraient être la taille de ce qui est dessiné à l'écran - qui dans votre cas serait le même sur les tablettes et les smartphones - peut tu vérifies ça?
AgentKnopf

Oui, je pense que je devrais dire ceci: lorsque je l'exécute sur ma tablette, même si la taille de l'écran est plus grande, tous les bitmaps sont de la même taille. Existe-t-il un moyen de faire en sorte que les bitmaps restent dans la même proportion même sur des écrans de tailles différentes?
user1404512

@ user1404512 Il est très important que vous répondiez à toutes les questions que nous vous avons posées, car nous ne savons toujours pas comment votre mise en page est conçue, ce qui rend difficile de répondre à une question spécifique. En ce qui concerne vos bitmaps: j'ai mis à jour ma réponse pour répondre à la question de la mise à l'échelle bitmap du mieux que je pouvais, étant donné que très peu de choses sont connues sur votre configuration.
AgentKnopf

Non, je n'utilise pas de moteur de jeu. J'ai ma disposition en xml, et dans mon fichier xml j'ai un SurfaceHolder.Callback qui est l'écran entier. La largeur et la hauteur du support changent d'un écran à l'autre. Je pense que mon problème est que je dessine les bitmaps avec les coordonnées X et Y, mais l'échelle des bitmaps reste la même d'un écran à l'autre. Y a-t-il un moyen de réparer ceci? Merci beaucoup d'avance!
user1404512

3

Il existe un bon article pertinent sur Android.com: http://developer.android.com/guide/practices/screens_support.html

Cette référence vous aide à trier par taille d'écran, densité d'écran et résolution. Le but est d'utiliser les API Android pour obtenir une «indépendance de densité» afin que les composants et les graphiques de votre interface utilisateur puissent bien paraître sur divers appareils.

N'oubliez pas que vous pouvez également créer différentes configurations de périphériques virtuels Android pour l'émulateur pendant que vous testez la disposition et l'apparence: http://developer.android.com/guide/developing/devices/emulator.html


0

Juste un coup dans le noir ici. Avez-vous défini la disposition principale pour remplir le parent à la fois verticalement et horizontalement?

En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.