Como faço para uma resolução de jogo 2D independente?

10

Estou trabalhando em um jogo 2D simples. Eu terminei a versão do telefone móvel.

No entanto, meu chefe quer que o jogo funcione no RT dele. Estou fazendo a "conversão", mas meus botões estão nos lugares errados, porque codifiquei o tamanho da tela, assim:

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

Neste exemplo, mainframeestá bom, mas startbrectnão está, porque eu defini o tamanho para corresponder à tela de um telefone Windows. Como posso lidar com o design responsivo quando as telas de todos os telefones com Windows 8 são diferentes? Existe uma fórmula ou macro para calcular cada vez que o bom tamanho?

Gabson
fonte
Você pode verificar qual porcentagem do Windows Phone dimensiona seus botões usados ​​e, em seguida, usar essa porcentagem para calcular o tamanho correto de tela para todas as outras resoluções. Mas tenho certeza de que existem maneiras mais elegantes do que isso.
Christian
Estou procurando uma maneira mais elegante, mas vou tentar com porcentagem no momento.
Gabson
2
Você deve conseguir manipular a câmera.
ashes999
Minha solução foi lidar com a porcentagem não encontrada melhor.
Gabson

Respostas:

17

Uso um tamanho de tela de referência e dimensiono tudo de acordo com ele, mantendo a proporção de tudo 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 garantir que o jogo tenha uma boa aparência em resoluções com proporções substancialmente diferentes das resoluções de referência, defina uma "área reproduzível" que se encaixe em qualquer tipo de tela e coloque todos os elementos visuais críticos da jogabilidade. Encha tudo fora dele com fundo. Normalmente, minha área reproduzível de referência é tão grande quanto o tamanho da tela de referência.

Nas orientações de retrato, calculo a (nova) área reproduzível para que a tela seja preenchida verticalmente e o espaço que ocupa horizontalmente seja tão grande quanto necessário para manter a proporção. Nas orientações da paisagem, preencho a tela horizontalmente e mantenho a proporção ao definir o tamanho vertical.

Para obter mais informações, consulte http://en.wikipedia.org/wiki/Safe_area_(television) , pois é um conceito semelhante, se não idêntico.


fonte
0

Eu acho que a abordagem mais fácil e natural para layouts independentes de resolução é um esquema relativo (percentual). Portanto, desde o início, não trabalhe com a resolução real, mas apenas em um quadrado uniforme de [0,1] x [0,1] sempre que possível.

Isso significa que, para uma posição dada screen_sizee uma posição dada object_sizee determinada (px, py)(por exemplo (0,5, 0,5) para o centro da tela), o canto superior esquerdo do objeto é calculado por:

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

A ideia deve estar clara. Uma abstração pronta seria

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

e toda posição é definida então por (cxi, cyi). Com isso, pode-se colocar objetos em cantos com ou sem bordas, etc.

Verifique se o tamanho dos elementos únicos (botões, etiquetas, ...) também está dimensionado.

Trilarion
fonte
-2

Especialmente para MonoGame, eu tenho uma solução independente de plataforma para esse problema chamado IRR (Independent Resolution Renderer). Tem uso muito simples:

  1. Criar IRR no método Initialize ()

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

  2. Chame _irr.Draw () cada ciclo na chamada Draw ()
  3. Forneça _irr.GetTransformationMatrix () em qualquer chamada SpriteBatch.Begin () que você deseja usar IRR.

A descrição está aqui: http://panthernet.ru/forum/index.php?/topic/17-monogamexna-examples-v14/?p=44

O código está aqui: https://github.com/panthernet/Monogame-Examples

Alexander Smirnov
fonte