将nine-patch图像作为Libgdx Scene2d按钮背景加载看起来很糟糕

5
我正在尝试将Nine Patch用作Libgdx Scene2d UI按钮的背景。它已经被加载,但是看起来非常丑陋。我可以看到“元数据”像素,并且它被拉伸得像普通图像一样(按钮上的文本是“Continue”): ugly image of a nine-patch button 我通过(libgdx)NinePatch直接将.9.png文件加载到(libgdx)NinePatchDrawable中,如下所示:
this.dialogButtonUp = new NinePatchDrawable(
   new NinePatch(new Texture(Gdx.files.internal("data/button-round.9.png"))));
this.dialogButtonDown  = new NinePatchDrawable(
   new NinePatch(new Texture(Gdx.files.internal("data/button-round-down.9.png"))));

然后我创建一个TextButtonStyle,用来描述按钮,并引用两个NinePatch可绘制对象:

TextButton.TextButtonStyle buttonStyle = new TextButton.TextButtonStyle();
buttonStyle.font =  aValidFontReally;
buttonStyle.fontColor = Color.BLACK;
buttonStyle.up = this.dialogButtonUp;
buttonStyle.down = this.dialogButtonDown;
buttonStyle.pressedOffsetX = -2;

我是通过一个对话框间接地构建按钮:

new Dialog( ... ).button("Continue", null, buttonStyle);

我已检查.9.png文件,以确保:

  • 在Eclipse中刷新了资产文件
  • 元数据边框像素要么完全不可见,要么完全可见为黑色
  • Android的draw9patch工具可以加载并验证这些图像

还有其他建议需要检查或更改吗?


尝试使用SpriteBatch和NinePatch.draw()绘制每个NinePatch,这样至少可以确定问题所在,即如果它能正常工作,则问题不在于NinePatch。 - R Hyde
好的观点!我刚试了一下,直接使用NinePatch.draw(...)也看到了同样的丑陋。所以DialogButton没有搞砸它。 - P.T.
2
查看NinePatch源代码(https://github.com/libgdx/libgdx/blob/master/gdx/src/com/badlogic/gdx/graphics/g2d/NinePatch.java),我认为如果您使用只带有单个Texture参数的构造函数,它并不会做太多事情。请尝试使用此构造函数:public NinePatch(Texture texture,int left,int right,int top,int bottom)。 - R Hyde
是的,看起来有“预处理”(即“.9.png”)和“后处理”九宫格纹理,而NinePatch用于后处理的纹理。创建TextureAtlas似乎会进行处理。我没有看到任何关于“.9.png”的运行时支持,但也许我还没有找对地方... - P.T.
1个回答

11
感谢@RodHyde的指引,看起来libgdx的NinePatch类是设计用于接受“后处理”九宫格纹理的(即,使用单独的整数值来描述如何将单个纹理切成图块)。这种“处理”通常发生在将“.9.png”文件打包到TextureAtlas中时(请参见https://github.com/libgdx/libgdx/wiki/Texture-packer#ninePatches)。纹理图集是一个非常好的想法(特别是当您的UI包含许多不同的纹理元素时),因此这是有道理的,但在开发和尝试运行某些东西时可能会有点令人惊讶。
为了解决这个问题,以便我可以直接包含“.9.png”文件,我写了这个:
private static NinePatch processNinePatchFile(String fname) {
    final Texture t = new Texture(Gdx.files.internal(fname));
    final int width = t.getWidth() - 2;
    final int height = t.getHeight() - 2;
    return new NinePatch(new TextureRegion(t, 1, 1, width, height), 3, 3, 3, 3);
}

这个代码加载纹理,创建一个子区域裁剪掉1像素的元数据边框,然后猜测九宫格边框元素为3像素宽/高。虽然通过在纹理数据中混淆来正确计算可能是可行的,但不值得付出这种努力 - 在这种情况下,只需将纹理放入图集中即可。

2
NinePatch的javadoc已经得到改进,以使其更加清晰:https://github.com/libgdx/libgdx/commit/5ce8dc04153234c760b3753fe3a6b4e6fe1653ea#gdx/src/com/badlogic/gdx/graphics/g2d/NinePatch.java - P.T.

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