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?


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.


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.


-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

Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.