Comment rendre une résolution de jeu 2D indépendante?

10

Je travaille sur un jeu 2D simple. J'ai terminé la version pour téléphone portable.

Cependant, mon patron veut que le jeu fonctionne sur sa RT. Je fais la "conversion" mais mes boutons sont au mauvais endroit, car j'ai codé en dur la taille de l'écran, comme ceci:

 texture = game.Content.Load<Texture2D>("StartScreen");
 mainFrame = new Rectangle(0, 0, game.GraphicsDevice.Viewport.Width, game.GraphicsDevice.Viewport.Height);

 // button definitions
 startbrect = new Rectangle(300, 258, 88, 88);
 startbtext = game.Content.Load<Texture2D>("bplay");

Dans cet exemple, mainframec'est bien, mais ce startbrectn'est pas le cas, car j'ai défini la taille pour qu'elle corresponde à l'écran d'un téléphone Windows. Comment gérer une conception réactive lorsque tous les écrans des téléphones Windows 8 sont différents? Existe-t-il une formule ou une macro pour calculer à chaque fois la bonne taille?

Gabson
la source
Vous pouvez vérifier quel pourcentage de la taille d'écran de Windows Phone vos boutons sont utilisés, puis utiliser ce pourcentage pour calculer la taille d'écran correcte pour chaque autre résolution. Mais je suis sûr qu'il existe des moyens plus élégants que cela.
Christian
Je cherche une manière plus élégante, mais je vais essayer avec un pourcentage pour le moment.
Gabson
2
Vous devriez pouvoir le faire en manipulant l'appareil photo.
ashes999
Ma solution était de ne pas trouver mieux le pourcentage.
Gabson

Réponses:

17

J'utilise une taille d'écran de référence et je redimensionne tout en fonction de celui-ci, tout en conservant le même rapport.

private static float CalcRatio(Vector2 Sizes)
{
    return Sizes.y/Sizes.x;
}

public static Vector2 CalculateNewPos(Vector2 RefPos, Vector2 RefScreenSize, 
                                      Vector2 CurrentScreenSize)
{       
    return new Vector2((RefPos.x/RefScreenSize.x) * CurrentScreenSize.x, 
                       (RefPos.y/RefScreenSize.y) * CurrentScreenSize.y);
}

public static Vector2 CalculateNewSize(Vector2 RefSize, Vector2 RefScreenSize,
                                       Vector2 CurrentScreenSize)
{       
    float origRatio = CalcRatio(RefSize);
    float perW = RefSize.x * 100f / RefScreenSize.x;    
    float newW = perW / 100f * CurrentScreenSize.x;
    float newH = newW * origRatio;
    return new Vector2(newW, newH);
}

Pour vous assurer que le jeu a une bonne résolution avec des ratios sensiblement différents de ceux de votre résolution de référence, définissez une "zone jouable", qui s'adapte à tout type d'écran, et placez-y tous les visuels critiques du gameplay. Remplissez tout ce qui se trouve à l'extérieur avec de l'arrière-plan. Habituellement, ma zone de lecture de référence est aussi grande que la taille de l'écran de référence elle-même.

En orientation portrait, je calcule la (nouvelle) zone de lecture de sorte que l'écran soit rempli verticalement et que l'espace qu'il occupe horizontalement soit aussi grand que nécessaire pour conserver le rapport. Sur les orientations paysage, je remplis l'écran horizontalement et garde le rapport lors du réglage de la taille verticale.

Pour en savoir plus, consultez http://en.wikipedia.org/wiki/Safe_area_(television) car il s'agit d'un concept similaire, sinon identique.


la source
0

Je pense que l'approche la plus simple et la plus naturelle pour les dispositions indépendantes de la résolution est un schéma relatif (en pourcentage). Donc, dès le départ, ne travaillez pas avec la résolution réelle, mais uniquement dans un carré uniforme [0,1] x [0,1] dans la mesure du possible.

Cela signifie que pour une position donnée screen_sizeet une object_sizeposition relative donnée (px, py)(par exemple (0,5, 0,5) pour le centre de l'écran), le coin supérieur gauche de l'objet est calculé par:

x = px * screen_size.width - 0.5 * object_size.width
y = py * screen_size.height - 0.5 * object_size.height

L'idée doit être claire. Une abstraction prête serait

x = cx1 * screen_size.width + cx2 * object_size.width + cx3
y = cy1 * screen_size.height + cy2 * object_size.height + cy3

et chaque position est définie ensuite par (cxi, cyi). Par cela, on pourrait placer des objets dans des coins avec ou sans bordures, etc.

Veuillez vous assurer que la taille des éléments individuels (boutons, étiquettes, ...) est également mise à l'échelle.

Trilarion
la source
-2

Spécialement pour MonoGame, j'ai une solution indépendante de la plate-forme pour ce problème appelée IRR (Independent Resolution Renderer). Il a une utilisation très simple:

  1. Créer un IRR dans la méthode Initialize ()

    _irr = nouveau ResolutionRenderer (this, VirtualResolutionWidth, VirtualResolutionHeight, _gfx.PreferredBackBufferWidth, _gfx.PreferredBackBufferHeight);

  2. Appelez _irr.Draw () à chaque cycle de l' appel Draw ()
  3. Approvisionnement _irr.GetTransformationMatrix () dans toute SpriteBatch.Begin () que vous appelez souhaitez utiliser TRI.

La description est ici: http://panthernet.ru/forum/index.php?/topic/17-monogamexna-examples-v14/?p=44

Le code est ici: https://github.com/panthernet/Monogame-Examples

Alexander Smirnov
la source