Como combinar o tamanho da fonte com a resolução da tela?

12

Então, eu estou trabalhando em um jogo usando LibGDX e tenho um problema.

Para fazer meu jogo se encaixar na maioria das resoluções, criei um ativo base para cada proporção, por exemplo, uma imagem de plano de fundo do menu principal, em 800X600 para 4: 3, 1280X720 para 16: 9 etc.

Agora estou tentando incorporar TextButtons no jogo, para as opções; Meu problema é que não consigo descobrir quais tamanhos de fonte correspondem a quais resoluções de tela. Existe uma maneira de descobrir isso, ou eu tenho que ir um por um através de cada uma das resoluções que tenho e apenas corresponder manualmente o texto à resolução?

Aon GoltzCrank
fonte

Respostas:

17

É fácil: as fontes não precisam corresponder à resolução, precisam corresponder à densidade de pixels .

A densidade de pixels é medida em pixels por polegada ( PPI ) ou pixels por centímetro. Há também uma unidade de medida chamada pixels independentes de densidade ( DP ) . É definido 1dpo tamanho de um pixel em uma 160 PPItela.

Agora, voltando às fontes, tente fazer este teste: coloque seu laptop em 720p. Dê uma olhada no tamanho da fonte. Agora conecte-o ao monitor de 1080p de 42 "da área de trabalho. Se o monitor exibir as informações corretas sobre seu tamanho, a fonte deverá ter EXATAMENTE o mesmo tamanho da tela de 720p. Imagine como seria estranho se o texto em seu O laptop tinha um tamanho diferente do texto do monitor do seu desktop.Com isso dito, resoluções maiores devem fornecer mais detalhes à fonte, telas maiores devem fornecer mais conteúdo a ser mostrado.

O mesmo fato pode ser observado nos editores de texto. Uma 72ptfonte deve ter a mesma aparência na tela quando impressa em papel.

Tudo isso significa que você provavelmente deve querer o mesmo tamanho em todos os tamanhos de tela (com algumas exceções). Se você deseja se basear em algum lugar, os sites geralmente usam 12ptfontes, o MS Windows usa 11pte 12ptfontes.

Este gráfico (também incluído na parte inferior da resposta) nos diz que o 12ptCSS é aproximadamente igual ao 16pxCSS (como se isso não fosse confuso o suficiente, um px no CSS é o mesmo que o dp em qualquer outro lugar), então digamos que você 16dpcriará suas fontes no LibGDX.

No seu jogo, use o FreeTypeFontGeneratorpara gerar fontes dinamicamente, assim você pode considerar a densidade da tela ao criá-las:

BitmapFont createFont(FreeTypeFontGenerator ftfg, float dp)
{
    return ftfg.generateFont((int)(dp * Gdx.graphics.getDensity()));
}
//On Init
BitmapFont buttonFont = createFont(arial, 16); //16dp == 12pt

Isso funciona porque Gdx.graphics.getDensity()é igual a YourScreenDensity/160, portanto, é um "fator de escala" para levar as coisas ao tamanho que elas teriam em uma tela de 160ppi.

Sobre as exceções que mencionei anteriormente: você provavelmente desejará redimensionar as fontes de acordo com o tamanho da tela em caso de logotipos, promoções, etc. , de qualquer forma.

A outra exceção é o texto em telas minúsculas. Telas de telefone de 4,5 polegadas ou menores, vestíveis. Normalmente, você não terá tempo para criar conteúdo de rolagem ou não poderá colocar tanto conteúdo nessa tela. Você pode tentar reduzir a fonte 1dp, como o o leitor provavelmente terá o telefone muito próximo do rosto, provavelmente não terá problemas para ler.Lembre-se de que pode incomodar o leitor que lê textos pequenos ilegíveis.

TL; DR:

  • O tamanho físico praticamente não muda diretamente com o tamanho ou a resolução da tela, mas com uma combinação de ambos ( screenSize/resolutiono famoso PPI)
  • Pense em pt e dp . Esqueça os pixels da tela até ter que desenhar o resultado final.
  • Crie sua fonte em tempo de execução com um tamanho razoável.
  • Convertendo dp em pixels da tela:pixels = dp * Gdx.graphics.getDensity();
  • Se você estiver usando um mecanismo que não há dará conversor para dp como LibGDX de Gdx.graphics.getDensity(), você pode tentar: densityFactor = Screen.getPixelsPerInch() / 160.0f, em seguida,pixels = dp * densityFactor

EDITAR:

2014, 25 de junho no Google IO, Matias anunciou uma nova diretriz de estilo para o Android, que inclui uma nova fonte de Roboto e diretrizes de tipografia. Tome esta tabela como um guia:

Diretrizes de tamanho de fonte do Android, obtidas em google.com/design

EDIT2:

Gráfico de tamanho de fonte CSS incluído, caso o link apodreça: Tamanhos de fonte CSS

Gustavo Maciel
fonte
1
+1, ótima resposta. A distância de visualização também é um fator muito importante. Você precisará de fontes maiores para jogos que rodam em um console / TV em comparação com as do PC ou mesmo de um Tablet (onde a distância de visualização é bastante curta).
bummzack
1
@ albummzack ótimo que você apontou isso! Você pode conseguir isso adicionando um fator de escala para a fórmula, como este: dp * Gdx.graphics.getDensity() * distanceFactor. Você pode transformar o distanceFactor uma constante e defini-lo ao 2compilar para console / TV, 1caso contrário. Claro que você deve encontrar melhores valores para isso.
Gustavo Maciel
Estou tendo problemas com isso. Quando coloco o tamanho do SP no gerador como tamanho para pixels, obtenho exatamente no meu aplicativo de desktop o mesmo tamanho dos da imagem e de outras fontes on-line. Quando eu multiplico, getDensity() == 0.6eles ficam ilegíveis na minha área de trabalho. Eles ficam pequenos, mas bem dimensionados no meu Galaxy S8, onde `getDensity () == 3 '. Eu mesmo calculei a densidade e eles parecem corretos, então segurei meu telefone próximo ao meu aplicativo de desktop e eles são iguais. Mas eles não deveriam ter o tamanho da imagem real exibida na minha área de trabalho?
Madmenyo
@ Madmenyo Esse é o fator de escala que eu falei. Você deve usar a escala de densidade para manter o tamanho do texto igual nos dispositivos com o mesmo fator de forma. Então, ao invés de apenas dp * getDensity(), provavelmente você deve fazer dp * getDensity() * scalingFactor, o que scalingFactordeve ser decidido em tempo de compilação, e algo como isso poderia funcionar: Celular: scalingFactor = 1Computador: scalingFactor = 3e TV: scalingFactor = 5. Brinque com esses números!
23718 Gustavo Maciel
GetDensity não retorna a densidade exata, como se vê. github.com/libgdx/libgdx/issues/5322#issuecomment-406902114, você precisa fazer algo como getPpiX() / 160)obter um resultado melhor. No entanto, getDensity()acho que faz um bom trabalho, na maioria dos casos.
Madmenyo