如何使字体大小与屏幕分辨率匹配?


12

因此,我正在使用LibGDX进行游戏,但遇到了问题。

为了使我的游戏适合大多数分辨率,我为每个高宽比创建了一个基础资产,例如主菜单背景图像,并以800X600(4:3),1280X720(16:9)等进行制作。

现在,我正在尝试将TextButtons纳入游戏,以供选择;我的问题是我无法弄清楚哪种字体大小与哪种屏幕分辨率匹配。有没有办法解决这个问题,还是我必须逐一检查我拥有的每个分辨率,然后手动将文本与该分辨率匹配?

Answers:


17

这很容易:字体不需要匹配分辨率,它们需要匹配像素密度

像素密度以像素每英寸(PPI)或像素/厘米来度量。还有一个称为密度无关像素(DP的度量单位。定义1dp为一个像素在160 PPI屏幕上的大小。

现在回到字体,尝试进行此测试:将笔记本电脑以720p运行。看一下字体大小。现在,将其插入台式机的1080p 42英寸显示器。如果显示器输出有关其大小的正确信息,则该字体的大小应该与720p屏幕上的大小完全相同。想象一下,如果您的文本在您的显示器上有多怪异笔记本电脑的大小与台式机显示器上的文本不同,也就是说,较大的分辨率应能提供更多的字体细节,较大的屏幕应能显示更多内容。

在文本编辑器上可以观察到相同的事实。一72pt字型应该看屏幕会在纸张上打印时相同的。

所有这些意味着您可能应该在所有显示尺寸上都希望有相同的尺寸(有些例外)。如果您想将自己放置在某个地方,则网站通常使用12pt字体,MS Windows使用11pt12pt字体。

这张表(也包含在答案的底部)告诉我们12ptCSS大致等于16pxCSS(好像这还不够令人困惑,CSS中的px在其他所有地方都与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)
  • 想想ptdp。忘记屏幕像素,直到必须绘制最终结果。
  • 在运行时以合理的大小创建字体。
  • dp转换为屏幕像素:pixels = dp * Gdx.graphics.getDensity();
  • 如果您使用的引擎无法像LibGDX的那样为您提供dp转换器,则Gdx.graphics.getDensity()可以尝试:densityFactor = Screen.getPixelsPerInch() / 160.0fpixels = dp * densityFactor

编辑:

2014年6月25日,Google IO上的Matias宣布了新的Android样式指南,其中包括新的Roboto字体和版式指南。将此表作为指导:

Android字号指南,取自google.com/design

编辑2:

随附的CSS字体大小图表,以防链接变烂: CSS字体大小


1
+1,好答案。观看距离也是一个非常重要的因素。与PC甚至平板电脑(观看距离很短)相比,在控制台/电视上运行的游戏需要更大的字体。
bummzack 2014年

1
@bummzack太好了,您指出了这一点!您可以通过在公式中添加比例因子来实现此目的,如下所示:dp * Gdx.graphics.getDensity() * distanceFactor。您可以将distanceFactor设为常数,然后2在为控制台/电视编译时将其定义为常数1。当然,您应该为此找到更好的价值。
Gustavo Maciel 2014年

我对此有疑问。当我将SP大小作为像素大小放到生成器中时,我在桌面应用程序上获得的图像大小与图像中的图像大小以及其他有关此内容的在线资源完全相同。当我乘以getDensity() == 0.6它们时,它们在我的桌面上不可读。它们虽然很小,但在我的Galaxy S8上尺寸很好,其中的getDensity()== 3。我自己计算了密度,它们看起来是正确的,然后我实际上将手机放在桌面应用程序旁边,它们的确相等。但是,它们是否不应该是我在桌面上查看的实际图像的大小?
Madmenyo '18年

@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
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.