BASIC 中的 Google 字体

只需指定一个字体家族名,就能得到真正的矢量文字,而不是一张位图字表,代价是异步加载所需要的等待,以及游戏导出之后会发生什么。

这是用来做什么的#

经典的 BASIC 是用一张字体图来绘制文字的:一整张字形表,通过 TextFontImage(text, image) 来设置。这套方式可以用,也一直是这门方言原本的做法,而且它会继续留在原地。但一张位图字表不能缩放,而且看起来就是它本来的样子。

LoadGoogleFont 换成了指定一个字体家族名:

font = LoadGoogleFont("Inter")
PrintFont(font)
Print("Hello")
DO
  Sync()
LOOP

没有任何东西被移除。LoadFontTextFontImage 和位图路径都照常可用,一个程序也可以把它们混着用。

这份等待不是可选的#

字体是一个文件,这个文件是在调用返回之后才到达的。如果在它到达之前就打印,最初几帧会用回退字体显示出来,读起来就像是"这个命令什么都没做"。

GoogleFontReady 就是用来等它的:

font = LoadGoogleFont("Inter")
ready = 0
DO
  IF ready = 0
    IF GoogleFontReady(font) = 1
      PrintFont(font)
      ready = 1
    ENDIF
  ENDIF
  Print("Hello")
  Sync()
LOOP

警告: 同一个陷阱曾经也困住过应用自己的模块。声明一个字体不等于加载它:一块画布只有在有东西真正索要一个字体家族的时候才会去下载它,而应答会在一帧甚至几帧之后才到达。

浏览字体家族列表#

这个引擎自带一份字体家族列表,一个程序可以读取它,这正是一款游戏内的字体选择器所需要的东西:

count = GoogleFontCount()
FOR i = 0 TO count - 1
  Print(GoogleFontName(i))
NEXT i

这份列表填充的是一个选择器,它本身不是一个限制。任何 Google 字体家族都可以通过 LoadGoogleFont 按名字加载,不管它有没有出现在这份列表里。

导出之后会发生什么#

游戏运行在哪里会发生什么
编辑器里第一次指定这个字体家族名时,会从 Google 拉取它。
浏览器导出一样,而且在导出工具能够打包它的情况下,这个文件会从构建产物里提供。
原生或 Bevy 构建这个文件必须已经随构建一起打包好。这里没有网络连接。

导出工具会读取你的程序,找出每一个你以明文字符串形式指定过的字体家族,下载它,并把它写入 assets/fonts/<Family>.woff2。这样构建出来的产物之后就能离线工作。

警告: 一个在运行时才计算出来的字体家族名,无法通过读取程序被发现,所以也就无法被打包进去。导出报告会说明这一点,构建产物会回退到默认字体。凡是需要挺过一次导出的地方,请写 LoadGoogleFont("Inter"),而不是 LoadGoogleFont(names[i])

命令一览#

命令作用
LoadGoogleFont(family)加载这个字体家族,返回一个 id
LoadGoogleFont(fontID, family)同上,用一个你自己指定的 id
GoogleFontReady(fontID)文件可用时返回 1
GoogleFontCount()这份列表提供多少个字体家族
GoogleFontName(index)列表中的一个字体家族名

其余的都是既有的字体机制:PrintFont(id) 用于 PrintTextFontSet(text, id) 用于一个 Text 对象,DeleteFont(id) 用来释放它。

进一步了解#