Come posso rendere indipendente una risoluzione di gioco 2D?


10

Sto lavorando a un semplice gioco 2D. Ho finito la versione del cellulare.

Tuttavia, il mio capo vuole che il gioco funzioni sul suo RT. Sto eseguendo la "conversione" ma i miei pulsanti sono nei posti sbagliati, perché ho codificato le dimensioni dello schermo, in questo modo:

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

In questo esempio, mainframeva bene, ma startbrectnon lo è, perché ho definito le dimensioni in modo che corrispondano allo schermo di un telefono Windows. Come posso gestire il design reattivo quando tutti gli schermi dei telefoni Windows 8 sono diversi? Esiste una formula o una macro per calcolare ogni volta la dimensione corretta?


È possibile verificare quale percentuale dello schermo di Windows Phone viene utilizzata per i pulsanti e quindi utilizzare tale percentuale per calcolare lo schermo corretto per ogni altra risoluzione. Ma sono sicuro che ci sono modi più eleganti di questo.
Christian,

Sto cercando un modo più elegante, ma proverò con percentuale per il momento.
Gabson,

2
Dovresti essere in grado di farlo manipolando la fotocamera.
ashes999,

La mia soluzione era gestire la percentuale non trovandola migliore.
Gabson,

Risposte:


17

Uso una dimensione dello schermo di riferimento e ridimensiono tutto in base a esso, mantenendo il rapporto di tutto uguale.

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

Per assicurarti che il gioco abbia un bell'aspetto su risoluzioni con rapporti sostanzialmente diversi da quelli della tua risoluzione di riferimento, definisci un '"area giocabile", che si adatti a qualsiasi tipo di schermo e metti lì tutte le immagini critiche del gameplay. Riempi tutto al di fuori di esso con lo sfondo. Di solito, la mia area giocabile di riferimento è grande quanto le dimensioni dello schermo di riferimento stesso.

Per gli orientamenti del ritratto, calcolo l'area (nuova) riproducibile in modo che lo schermo sia riempito verticalmente e lo spazio che occupa in orizzontale sia grande quanto è necessario per mantenere il rapporto. Sugli orientamenti orizzontali, riempio lo schermo in orizzontale e mantengo il rapporto durante l'impostazione della dimensione verticale.

Per di più, vedi http://en.wikipedia.org/wiki/Safe_area_(television) in quanto è un concetto simile, se non identico.


0

Penso che l'approccio più semplice e più naturale ai layout indipendenti dalla risoluzione sia uno schema relativo (percentuale). Quindi dall'inizio non lavorare con la risoluzione reale ma solo in un quadrato uniforme [0,1] x [0,1] ove possibile.

Ciò significa che per una data screen_sizee una data object_sizee una data posizione relativa (px, py)(ad esempio (0,5, 0,5) per il centro dello schermo), l'angolo superiore sinistro dell'oggetto viene calcolato da:

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

L'idea dovrebbe essere chiara. Un'astrazione pronta sarebbe

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

e ogni posizione viene definita da (cxi, cyi). Con questo si potrebbero posizionare oggetti negli angoli con o senza bordi, ecc.

Assicurati che anche le dimensioni dei singoli elementi (pulsanti, etichette, ...) siano ridimensionate.


-2

In particolare per MonoGame ho una soluzione indipendente dalla piattaforma per questo problema chiamato IRR (Independent Resolution Renderer). Ha un utilizzo molto semplice:

  1. Crea IRR nel metodo Initialize ()

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

  2. Chiamare _irr.Draw () ogni ciclo nella chiamata Draw ()
  3. Fornire _irr.GetTransformationMatrix () in qualsiasi chiamata SpriteBatch.Begin () che si desidera utilizzare IRR.

La descrizione è qui: http://panthernet.ru/forum/index.php?/topic/17-monogamexna-examples-v14/?p=44

Il codice è qui: https://github.com/panthernet/Monogame-Examples

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.