在我的PlayN游戏的HTML版本中,如何可靠地加载字体以便在启动时显示文本?

时间:2012-07-22 18:06:55

标签: playn

我正在使用PlayN的v1.3.1。以下google网上论坛讨论了这个问题,但我不确定如何实施建议的建议:

https://groups.google.com/forum/?fromgroups#!topic/playn/kiE2iEYJqM0

也许有人可以提供一些示例代码。目前,我正在遵循此答案中HTML link中引用的技术:

https://stackoverflow.com/a/9116829/1093087

我的问题:在游戏的主屏幕上,我使用加载的字体显示一些文字。适用于Java版本。但是,在HTML版本中,文本最初不会显示。在下一个屏幕上,或者如果我稍后返回主屏幕,将正确显示文本。所以我得出结论,这是由于谷歌组线程中讨论的异步加载字体。

我的补救措施是添加一个启动画面,显示图像几秒钟,让字体有机会加载,然后重定向到屏幕上显示文字。但无论我设置延迟多长时间,文本仍然不会显示。

这是我的HTML文件加载我的游戏和字体:

<!DOCTYPE html>
<html>
  <head>
    <title>mygamePlayn</title>
    <!-- fonts -->
    <style>
      @font-face {
        font-family: "DroidSans-Bold";
        src: url(mygame/fonts/DroidSans-Bold.ttf);
      }
      @font-face {
        font-family: "UbuntuMono";
        src: url(mygame/fonts/UbuntuMono-Bold.ttf);
      }
    </style>
  </head>
  <body bgcolor="black">
    <script src="mygame/mygame.nocache.js"></script>
  </body>
</html>

这是我的核心Java代码,它生成最初未显示的文本(但不是以其他方式工作):

public static CanvasImage generateTextImage(String text, String fontName,
    Integer fontSize, Integer fontColor, Style fontStyle, Integer padding) {
    Font font = graphics().createFont(fontName, fontStyle, fontSize);
    TextFormat fontFormat = new TextFormat().withFont(font).withTextColor(fontColor);

    TextLayout layout = graphics().layoutText(text, fontFormat);
    Integer width = (int) layout.width() + padding * 2;
    Integer height = (int) layout.height() + padding * 2;

    CanvasImage textImage = graphics().createImage(width, height);
    textImage.canvas().drawText(layout, padding, padding);

    return textImage;
}

1 个答案:

答案 0 :(得分:2)

我想我终于想出了解决问题的方法。它需要在以下有点迂回的方式中使用Google WebFont Loader

1)我在PlayN项目的resources/fonts目录中保存了字体 - 在本例中为DroidSans-BoldInconsolataUbuntuMono-Bold

2)在resources/css中,我添加了一个fonts.css样式表,我在其中添加了@font-face我本地保存字体的定义。我的fonts.css文件:

@font-face {
    font-family: DroidSans;
    src: url('../fonts/DroidSans-Bold.ttf');
}
@font-face {
    font-family: Inconsolata;
    src: url('../fonts/Inconsolata.ttf');
}
@font-face {
    font-family: UbuntuMono;
    src: url('../fonts/UbuntuMono-Bold.ttf');
}
@font-face {
    font-family: UbuntuMono;
    font-weight: bold;
    src: url('../fonts/UbuntuMono-Bold.ttf');
}

注意:我使用与我在PlayN代码中使用的字体名称相同的font-family名称值。例如,我在我的PlayN代码中加载DroidSans字体,如下所示:

Font font = graphics().createFont("DroidSans", fontStyle, fontSize);

3)然后我在游戏的html文件(MyGame.html)中使用Google WebFont Loader在游戏加载之前加载字体。我的MyGame.html文件:

<!DOCTYPE html>
<html>
  <head>
    <title>MyGame</title>
    <style>
      body {
        background-color:black;
        color:white;
      }
    </style>

    <!-- Google AJAX Libraries API -->
    <script src="http://www.google.com/jsapi"></script>
    <script>
        google.load("jquery", "1.4.2");
        google.load("webfont", "1");

      WebFontConfig = {
        custom: { families: ['DroidSans', 'UbuntuMono'],
          urls: [ 'mygame/css/fonts.css' ]
        },
        loading: function() {
          console.log("loading fonts");
        },
        fontloading: function(fontFamily, fontDescription) {
          console.log("loading font: " + fontFamily + "-" + fontDescription);
        },
        fontactive: function(fontFamily, fontDescription) {
          console.log(fontFamily + "-" + fontDescription + " is active");        
        },
        fontinactive: function(fontFamily, fontDescription) {
          console.log(fontFamily + "-" + fontDescription + " is INACTIVE");
        },
        active: function() {
          console.log("font-loading complete");
        },
      };

      google.setOnLoadCallback(function() {
        console.log("Google onLoad callback");
        WebFont.load(WebFontConfig);
      });
    </script>

  </head>

  <body>
    <div id="playn-root">
        &nbsp;
        <script src="mygame/mygame.nocache.js"></script>
    </div>
  </body>

</html>

登录WebFont.load回调的控制台有助于验证在PlayN游戏代码之前字体是否已成功加载。

我更倾向于使用WebFont Loader和通过googleapis.com提供的字体,但我无法弄清楚如何同步我的PlayN代码和样式表之间的引用。 (现在我看一下,如果我不想自己托管这些字体,我想我可能刚刚使用了googleapi.com样式表中列出的相同网址。)无论如何,这种模式似乎解决了这个问题*

*适用于Google Chrome。我还没有测试过任何其他浏览器。