Как сопоставить размер шрифта с разрешением экрана?

12

Поэтому я работаю над игрой, использующей LibGDX, и у меня есть проблема.

Чтобы моя игра соответствовала большинству разрешений, я создал базовый ресурс для каждого соотношения сторон, например, фоновое изображение главного меню, я сделал его в 800X600 для 4: 3, 1280X720 для 16: 9 и т. Д.

Сейчас я пытаюсь включить TextButtons в игру, для вариантов; Моя проблема в том, что я не могу понять, какой размер шрифта соответствует разрешению экрана. Есть ли способ выяснить это, или мне нужно пройти по одному через каждое из имеющихся у меня разрешений и просто вручную сопоставить текст с разрешением?

Aon GoltzCrank
источник

Ответы:

17

Это просто: шрифты не должны соответствовать разрешению, они должны соответствовать плотности пикселей .

Плотность пикселей измеряется в виде пикселей на дюйм ( PPI ) или пикселей на сантиметр. Также есть единица измерения, называемая независимыми пикселями плотности ( DP ) . Определено, что 1dpэто размер одного пикселя на 160 PPIэкране.

Теперь вернемся к шрифту, попробуйте выполнить этот тест: переведите ноутбук в режим 720p. Посмотрите на размер шрифта. Теперь подключите его к 42-дюймовому монитору 1080p вашего рабочего стола. Если ваш монитор выводит правильную информацию о своем размере, шрифт должен иметь ТОЧНО такой же размер, как на экране 720p. Представьте себе, как странно было бы, если бы текст в вашем Размер ноутбука не совпадает с размером текста на мониторе настольного компьютера. При этом большие разрешения должны давать больше деталей шрифту, а большие экраны - больше контента для отображения.

Тот же факт можно наблюдать в текстовых редакторах. 72ptШрифт должен выглядеть на экране то же самое было бы при печати на бумаге.

Все это означает, что вам, вероятно, нужен одинаковый размер для всех размеров дисплея (за некоторыми исключениями). Если вы хотите где-то обосноваться, веб-сайты обычно используют 12ptшрифты, MS Windows использует 11ptи 12ptшрифты.

Эта диаграмма (также включенная в нижнюю часть ответа) говорит нам, что 12ptв CSS примерно то же самое, что 16pxи в CSS (Как будто это не слишком запутанно, px в CSS такой же, как и в других местах dp ), так что давайте скажем, что сделаю ваши шрифты 16dpна LibGDX.

В вашей игре используйте FreeTypeFontGeneratorдинамическую генерацию шрифтов, так что вы можете учитывать плотность экрана при их создании:

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

Это работает, потому что Gdx.graphics.getDensity()равно, YourScreenDensity/160таким образом, является «масштабным фактором», чтобы привести вещи к размеру, которым они были бы на экране 160ppi.

Об исключениях, которые я упоминал ранее: вы, вероятно, захотите изменить размер шрифтов в соответствии с размером экрана в случае логотипов, промо и т. Д. Но имейте в виду, что вам будет лучше делать это в графическом редакторе, таком как Photoshop или Gimp. , тем не мение.

Другое исключение - текст на крошечных экранах. Телефоны с диагональю 4,5 дюйма или меньше, носимые. Обычно у вас не будет времени для прокрутки контента, или вы просто не сможете позволить себе размещать столько контента на этом экране. Вы можете попытаться уменьшить шрифт 1dp, так как Читатель, вероятно, будет располагать телефон очень близко к лицу, у него, вероятно, не будет проблем с чтением. Имейте в виду, что вы можете раздражать игрока чтением нечитаемого мелкого текста.

TL; DR:

  • Физический размер примерно не изменится напрямую с размером экрана или разрешением, но с комбинацией обоих ( screenSize/resolutionизвестный PPI)
  • Подумайте о пт и дп . Забудьте о пикселях экрана, пока не начнете рисовать окончательный результат.
  • Создайте свой шрифт во время выполнения с разумным размером.
  • Преобразование dp в пиксели экрана:pixels = dp * Gdx.graphics.getDensity();
  • Если вы используете движок, который не дает вам конвертер в dp, как в LibGDX Gdx.graphics.getDensity(), вы можете попробовать:, densityFactor = Screen.getPixelsPerInch() / 160.0fзатемpixels = dp * densityFactor

РЕДАКТИРОВАТЬ:

2014, 25 июня на Google IO, Matias объявил о новых правилах стиля для Android, которые включают новые правила шрифтов и типографики Roboto. Возьмите эту таблицу в качестве руководства:

Рекомендации по размеру шрифта Android, взяты из google.com/design

EDIT2:

Включена таблица размеров шрифта CSS на случай, если ссылка испортится: Размер шрифта CSS

Густаво Масиэль
источник
1
+1, отличный ответ. Расстояние просмотра также является очень важным фактором. Вам понадобятся более крупные шрифты для игр, которые запускаются на консоли / телевизоре, по сравнению с играми для ПК или даже планшета (где расстояние просмотра довольно мало).
bummzack
1
@bummzack здорово, что ты указал на это! Вы можете достичь этого путем добавления коэффициента масштабирования к формуле, как это: dp * Gdx.graphics.getDensity() * distanceFactor. В противном случае вы можете сделать distanceFactor константой и определить его 2при компиляции для консоли / ТВ 1. Конечно, вы должны найти лучшие значения для этого.
Густаво Масиэль
У меня проблемы с этим. Когда я просто помещаю размер SP в генератор в качестве размера для пикселей, я получаю в своем настольном приложении точно такой же размер, что и на изображении, и другие онлайн-источники об этом. Когда я умножаю их, getDensity() == 0.6они не читаются на моем рабочем столе. Они становятся маленькими, но хорошими по размеру на моей Galaxy S8, где `getDensity () == 3 '. Я сам рассчитал плотность, и они кажутся правильными, затем я фактически держал свой телефон рядом с настольным приложением, и они действительно равны. Но не должны ли они соответствовать размеру реального изображения, просматриваемого на моем рабочем столе?
Madmenyo
@Madmenyo Это коэффициент масштабирования, о котором я говорил. Следует использовать масштабирование плотности, чтобы сохранить размер текста на устройствах с одинаковым форм-фактором. Таким образом , вместо того , чтобы просто dp * getDensity(), вероятно , вы должны сделать dp * getDensity() * scalingFactor, что scalingFactorдолжно быть принято во время компиляции, и что - то подобное может работать: Телефоны: scalingFactor = 1Компьютер: scalingFactor = 3и ТВ: scalingFactor = 5. Играй с этими числами!
Густаво Масиэль
GetDensity не возвращает точную плотность, как оказалось. github.com/libgdx/libgdx/issues/5322#issuecomment-406902114 вы должны сделать что-то вроде, getPpiX() / 160)чтобы получить лучший результат. Тем getDensity()не менее, в большинстве случаев я справляюсь с работой достаточно хорошо.
Madmenyo