¿Cómo hago que la resolución de un juego en 2D sea independiente?

10

Estoy trabajando en un juego 2D simple. He terminado la versión del teléfono móvil.

Sin embargo, mi jefe quiere que el juego funcione en su RT. Estoy haciendo la "conversión" pero mis botones están en los lugares equivocados, porque codifiqué el tamaño de la pantalla, de esta manera:

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

En este ejemplo, mainframeestá bien, pero startbrectno lo está, porque definí el tamaño para que coincida con la pantalla de un teléfono con Windows. ¿Cómo puedo manejar el diseño receptivo cuando todas las pantallas de los teléfonos con Windows 8 son diferentes? ¿Hay una fórmula o macro para calcular cada vez que el buen tamaño?

Gabson
fuente
Puede verificar qué porcentaje del tamaño de pantalla de Windows Phone usa sus botones y luego usar ese porcentaje para calcular el tamaño de pantalla correcto para cualquier otra resolución. Pero estoy seguro de que hay formas más elegantes que esta.
Christian
Estoy buscando una forma más elegante, pero intentaré con el porcentaje por el momento.
Gabson
2
Deberías poder hacerlo manipulando la cámara.
cenizas999 12/12/2013
Mi solución fue lidiar con el porcentaje que no encontré mejor.
Gabson

Respuestas:

17

Utilizo un tamaño de pantalla de referencia y escalo todo de acuerdo con él, manteniendo la proporción de todo igual.

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

Para asegurarse de que el juego se vea bien en resoluciones con proporciones sustancialmente diferentes a las de su resolución de referencia, defina un "área jugable" que se ajuste a cualquier tipo de pantalla y coloque todas las imágenes críticas del juego allí. Rellene todo fuera de él con el fondo. Por lo general, mi área jugable de referencia es tan grande como el tamaño de la pantalla de referencia.

En las orientaciones de retrato, calculo el (nuevo) área jugable para que la pantalla se llene verticalmente, y el espacio que ocupa horizontalmente es tan grande como se requiere para mantener la relación. En las orientaciones horizontales, lleno la pantalla horizontalmente y mantengo la relación cuando configuro el tamaño vertical.

Para obtener más información, consulte http://en.wikipedia.org/wiki/Safe_area_(television) ya que es un concepto similar, si no idéntico.


fuente
0

Creo que el enfoque más fácil y natural para los diseños independientes de resolución es un esquema relativo (porcentaje). Desde el principio, no trabaje con la resolución real, sino solo en un cuadrado uniforme [0,1] x [0,1] siempre que sea posible.

Eso significa que para una posición relativa dada screen_sizey una dada object_sizey dada (px, py)(por ejemplo (0.5, 0.5) para el centro de la pantalla), la esquina superior izquierda del objeto se calcula mediante:

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

La idea debe ser clara. Una abstracción lista sería

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

y cada posición se define entonces por (cxi, cyi). Por este se podrían colocar objetos en esquinas con o sin bordes, etc.

Asegúrese de que el tamaño de los elementos individuales (botones, etiquetas, ...) también esté escalado.

Trilarion
fuente
-2

Especialmente para MonoGame, tengo una solución independiente de la plataforma para este problema llamada IRR (Renderizador de resolución independiente). Tiene un uso muy simple:

  1. Crear IRR en el método Initialize ()

    _irr = nueva ResoluciónRenderer (esto, VirtualResolutionWidth, VirtualResolutionHeight, _gfx.PreferredBackBufferWidth, _gfx.PreferredBackBufferHeight);

  2. Llame a _irr.Draw () cada ciclo en la llamada Draw ()
  3. Proporcione _irr.GetTransformationMatrix () en cualquier llamada SpriteBatch.Begin () que quiera usar IRR.

La descripción está aquí: http://panthernet.ru/forum/index.php?/topic/17-monogamexna-examples-v14/?p=44

El código está aquí: https://github.com/panthernet/Monogame-Examples

Alexander Smirnov
fuente