Libgdx FreeTypeFont:动态生成的字体在标签中无法缩放

3
我正在尝试为我的全新游戏实现HUD界面。我想使用scene2d.ui小部件集来创建它,因为我听说它更适合响应式UI。因此,我正在尝试创建一个简单的HUD,其中有一个得分标签对齐在屏幕的右上方,以及一个暂停按钮放置在屏幕的左上方。
现在...我正在使用根表格(如表格指南https://github.com/libgdx/libgdx/wiki/Table#quickstart中所述)来填充舞台。
我想创建一个自定义类来处理所有的HUD界面,例如:
public class Hud extends Table{

    private Label scoreLabel;
    private Button pauseButton;

    public Hud(){
      setFillParent(true);

      BitmapFont font = (BitmapFont)    MyGame.assetManager.get(Constants.COUNTERS_FONT_NAME);

      LabelStyle labelStyle = new LabelStyle(font,Color.WHITE);
      scoreLabel = new Label("score:0", labelStyle);

      add(scoreLabel).width(2).height(1);

   }
}

我正在处理的问题是:标签内的文本不会停留在标签内。我的意思是:启用调试模式后,我可以看到代表标签的矩形具有正确的尺寸...但文本完全超出了边界并且无法缩放。
如您所见,我使用的字体是在游戏启动时通过FreeTypeFont库生成的BitmapFont...然后将该字体添加到游戏的AssetsManager中。
我发布用于将字体生成器添加到资产管理器的代码:
    //Register the FreeTypeFontGeneratorLoader
    InternalFileHandleResolver resolver = new InternalFileHandleResolver();
    assetManager.setLoader(FreeTypeFontGenerator.class, new FreeTypeFontGeneratorLoader(resolver));
    assetManager.setLoader(BitmapFont.class, ".ttf", new FreetypeFontLoader(resolver));


    //Load fonts
    FreeTypeFontLoaderParameter countersFontParameters = new FreeTypeFontLoaderParameter();
    countersFontParameters.fontFileName = Constants.BASE_FONT_NAME;
    countersFontParameters.fontParameters.size = 45;
    countersFontParameters.fontParameters.borderColor = Color.BLACK;
    countersFontParameters.fontParameters.borderWidth = 1;

    assetManager.load(Constants.COUNTERS_FONT_NAME, BitmapFont.class, countersFontParameters);

如您所见,我只加载了一个大小为45像素的BitmapFont。

我不知道问题出在哪里;我想尝试使用经典的.fnt格式的BitmapFont来查看问题是否在生成BitmapFont的方式上,但我也想保留FreeTypeFont的解决方案。

提前感谢您的帮助,

Luca

P.S.

关于舞台的一件事...它使用ScalingViewport,因此尺寸不是以像素为单位而是以虚拟单位为单位(因为我的游戏使用Box2d,我需要一个用于渲染和物理模拟的通用单位)。


我已经尝试使用由.fnt文件生成的BitmapFont,但没有任何变化。 - Luca Marzi
2个回答

3

我非常确定,只有在显式调用label.setFontScale( theScale )之后,标签才会响应视口的自动缩放。

在我看来,最好的方法是创建另一个专门用于HUD的舞台,这样你就可以拥有一个使用ScalingViewport的舞台(我承认我从未使用过它-使用一些Fill或类似的东西不是更好吗?)和另一个用于FitViewport的舞台。我认为这非常合理和直观,就像在驾驶汽车时在你的汽车挡风玻璃上显示你的HUD一样。

代码应该如下所示:

    //in your show method
    viewport = createYourScalingViewport();     
    stage = new Stage();    

    stage.setViewport(viewport);

    HUDviewport = new FitViewport(screenWidth, screenHeight);
    HUDstage = new Stage();

    HUDstage.setViewport(HUDviewport);

    ...

    //adding some actor to stages
    stage.addActor(actor1);
    stage.addActor(actor2);

    //BUT
    HUDstage.addActor( yourHudInstance );

    ...

    //then in your render method act() and draw() stage then HUDstage so the HUD will be above stage
    stage.act();
    stage.draw();

    HUDstage.act();
    HUDstage.draw();

记得resize屏幕方法中更新HUDviewport以适应窗口大小调整


嗨,为HUD创建一个不同的阶段的想法很好,我已经考虑过了,因为实际上GameStage和HudStage相互独立(或多或少...因为一些关于GameStage上的演员的信息应该在Hud上可见)。 无论如何,问题是我无法相信Label widget是如此无用,我的意思是:如果它仅调用font.draw()而不关心文本呈现的尺寸,那么它有什么作用呢? 换行行为是不够的... - Luca Marzi
我认为最好的方法是创建自己的小部件,使用简单字体并自行绘制所需的文本... - Luca Marzi
我认为作为包装器的Label不能修改位图字体的渲染图像,这就是为什么它在调用setFontScale之前不关心文本大小的原因 - 是的,创建自己的小部件来处理似乎是正确的选择。但是我很好奇你是否真的需要缩放字体 :) FitViewport会为您提供适当的缩放 - 您只需设置固定大小,然后不必担心 - 如果您想更改字体大小(例如进行某些动画),则可以轻松使用setFontScale() - m.antkowicz

0

我想我解决了我的问题。 看起来设置标签尺寸没有意义。

如果有人需要一个容器,紧贴着标签内呈现的文本,最好的解决方案是创建一个自定义类,像下面这样扩展HorizonaltGroup(或VerticalGroup)。

假设我需要一个游戏得分标签:

public class ScoreLabel extends HorizontalGroup{

 ...

}

在这个类里,我创建了一个标签属性,并将其添加为一个演员。
public class ScoreLabel extends HorizontalGroup{

 private Label scores;
 public static final float FONT_SCALE = 0.9f;

 public ScoreLabel(){

    BitmapFont font = MyGame.assetManager.get(Constants.COUNTERS_FONT_NAME);
    LabelStyle labelStyle = new LabelStyle(font, Color.WHITE);
    scores = new Label(getScoreText(), labelStyle);
    scores.setAlignment(Align.left);
    scores.setFontScale(FONT_SCALE);   


    addActor(scores);
 }

}

如果您激活调试模式,您会注意到有一个容器与文本完美地紧密呈现。

上面的代码只是加载了先前在游戏资产管理器中加载的BitmapFont。

然后应用字体缩放...我想它可以添加到皮肤属性中

无论如何...这对我来说是最好的解决方案。

我仍然使用带有ScalingViewport的舞台,以便我不必使用像素作为单位,所有尺寸都被缩放以填充设备屏幕。

再见,

Luca


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接