LibGDX开发日常#2

本文非面向libGDX入门用户,仅为个人日常记录。

相关关键词:Skin-Composer, gdx-vfx

绕不开的控件Skin-Composer

虽然我用着gdx-lml很舒服,但是想要深度定制自己的界面终究还是绕不开使用Skin-Composer。这玩意真的太折磨了,但是又不能不用,gdx-lml基本上都是从skin里取样式的。

一堆的Bug,真是被恶心的不要不要的,包括但不限于:

  1. 动不动就有些资源对不上——例如删了个资源,原来配置好的使用了这个资源的属性值就变空了,导出skin时也不报错,到游戏运行的时候就报错了,还好libGDX的skin解析报错还算合理,不然就要死了。
  2. 有些控件(指Skin-Composer自己的控件),例如设置一个颜色的rgb值的输入框,必须在任何时刻保证是个数字,我特么就是想删掉输入一个新的数字——对不起,全部删掉之后不能解析成数字了,于是Skin-Composer crash了!
  3. 有些控件之间的style有parent关系,在libGDX读取skin的时候会一边解析配置一边关联parent关系,而如果继承style的控件在json中先于parent的控件出现,对不起,游戏启动crash了,他妈的报找不到parent的那个类型。Skin-Composer不会对style的继承关系进行管理,每次export出去还得手动改下json里的位置,经过这波摧残我是真的受不了了,直接不要使用Style的继承保住心智,不然要发疯了。
  4. 虽然Skin-Composer的官方GIthub页面上 有说哪些不错Skin可以下载,但是有些(多数)Skin是从老版本制作的,那些Skin下载下来之后直接倒进去9成是要出错的,那时候反而更加麻烦,还不如直接用vis-ui的皮肤先临时用着。但是vis-ui的默认皮肤文件里面东西很多,atlas里面的素材也很乱,根本不知道哪个是哪个,最后还是自己从0开始做个皮肤好了。这也是下一小节的内容。
  5. 反正还有些其他的bug,就是崩的莫名其妙,总之就是一定要制作一个scmp项目来管理皮肤,频繁保存,绝对不能在游戏读取的json上改!

Skin的定制还是应该从0开始

其实从0开始最大的好处就是我其实根本用不到所有的控件,所以如果上来给我贴全部皮肤的样式我会直接懵逼的。我甚至不知道那些控件的属性要放什么,反而加大了我配置皮肤的难度。
所以,个人认为自制libGDX皮肤最好的方法是,首先写使用默认的样式写好你自己的应用的基本UI界面,之后把读取的skin换成一个空的skin,启动游戏,报错里面缺哪个Style就加哪个Style,就从默认的样式里把这个样式加进来。经过一次一次的报错,就可以把所有需要定制的样式全部写完。

Skin的TTF支持

虽然这libGDX官网有介绍怎么在gwt下使用TTF,但是Skin文件里是不带TTF字体配置支持的,而Skin-Composer倒是在导入TTF文件的界面有个指引,算是个加分项吧。这里把类贴一下吧,避免下次自己什么时候忘了。

public class TtfSupportSkin extends Skin {

    public TtfSupportSkin(FileHandle skinFile) {
        super(skinFile);
    }

    @Override
    protected Json getJsonLoader(final FileHandle skinFile) {
        Json json = super.getJsonLoader(skinFile);
        final Skin skin = this;
        json.setSerializer(FreeTypeFontGenerator.class, new Json.ReadOnlySerializer<FreeTypeFontGenerator>() {
            @Override
            public FreeTypeFontGenerator read(Json json,
                                              JsonValue jsonData, Class type) {
                String path = json.readValue("font", String.class, jsonData);
                jsonData.remove("font");

                FreeTypeFontGenerator.Hinting hinting = FreeTypeFontGenerator.Hinting.valueOf(json.readValue("hinting",
                    String.class, "AutoMedium", jsonData));
                jsonData.remove("hinting");

                Texture.TextureFilter minFilter = Texture.TextureFilter.valueOf(
                    json.readValue("minFilter", String.class, "Nearest", jsonData));
                jsonData.remove("minFilter");

                Texture.TextureFilter magFilter = Texture.TextureFilter.valueOf(
                    json.readValue("magFilter", String.class, "Nearest", jsonData));
                jsonData.remove("magFilter");

                FreeTypeFontGenerator.FreeTypeFontParameter parameter = json.readValue(FreeTypeFontGenerator.FreeTypeFontParameter.class, jsonData);
                parameter.hinting = hinting;
                parameter.minFilter = minFilter;
                parameter.magFilter = magFilter;
                FreeTypeFontGenerator generator = new FreeTypeFontGenerator(skinFile.parent().child(path));
                BitmapFont font = generator.generateFont(parameter);
                skin.add(jsonData.name, font);
                if (parameter.incremental) {
                    generator.dispose();
                    return null;
                } else {
                    return generator;
                }
            }
        });
        return json;
    }
}

gdx-vfx屏幕特效踩坑

这个项目gdx-vfx其实看着还挺帅的,所以拿来试了一下,效果是杠杠滴。不过内置的这些特效都太夸张了,只能用来预览效果,实际使用还是要自己做修改。

于是在试玩的过程中就有一些小发现:

  1. Stage的root actor最好是Window类,否则,在某些Viewport下窗口缩放时会有奇怪的现象,例如在ExtendViewport中以table为root时,对窗口做缩放会出现奇怪的偏移,貌似是Window类有一些特殊的置于屏幕中的定位逻辑。(虽然这个跟gdx-vfx没关系)、
  2. gdx-vfx貌似不兼容FitViewport的Stage,至少我试了所有的Viewport,只有FitViewport会在窗口缩放的时候控件会出现一些奇怪的裁剪。
  3. Shader在编译的时候居然会优化掉一些不用的参数,导致我想做一个通用的效果类型来做传参用途行不通(因为参数不存在了),不过这个可以通过设置ShaderProgram.pedantic = false,让他不需要强行要求所有参数都存在。不过既然默认这么要求肯定是有道理的,估计是为了性能着想,毕竟跟渲染有关系的东西,那么就整通用的呗。

最近的就这些吧。

这几天(主要界面的)UI基本上画好了,接下来可以狠狠地写代码实现了。真是个奇怪的习惯,应该是从安卓开发时期落下的,只当有了完整的设计图我才有开发动力,希望这周能实现个最最最粗略能跑的DEMO.

Leave a Reply

Your email address will not be published. Required fields are marked *