1

我正在使用 PlayN 的 v1.3.1。此问题在以下 google groups 线程中进行了讨论,但我不确定如何实施所提出的建议:

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

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

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

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

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

这是加载我的游戏和字体的 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;
}
4

1 回答 1

2

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

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

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 代码中用于字体名称的值相同。例如,我在 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 样式表中列出的相同 url。)无论如何,这种模式似乎可以解决问题.*

*适用于谷歌浏览器。我还没有测试任何其他浏览器。

于 2012-07-26T04:49:04.467 回答