LibGDX中翻转TextureRegion创建的NinePatchDrawable无法作为Table背景问题
我尝试执行以下操作:
TextureRegion region = new TextureRegion(new Texture("path to the file")); region.flip(false, true); NinePatch patch = new NinePatch(region, left, right, up, down); NinePatchDrawable drawable = new NinePatchDrawable(patch); Table table = new Table(); table.setBackground(drawable); table.add(someLabel);将Table添加到Stage后,仅能看到标签,背景不显示;但未翻转TextureRegion时该功能正常,请问这是什么原因?
问题根源
这其实是因为NinePatch的拉伸区域定义是基于原始TextureRegion的坐标系统,当你调用flip()方法后,TextureRegion的UV坐标被反转了,但NinePatch的left/right/up/down参数还是沿用了原始纹理的像素值,这直接导致拉伸区域的计算完全错乱——简单说,翻转后NinePatch找不到正确的可拉伸边缘和区域,自然就渲染不出背景了。
举个实际例子:假设你的原始纹理高度是100px,你设置up=20、down=20,这代表顶部20px、底部20px是固定边缘,中间60px是可拉伸区域。但当你垂直翻转(flip(false, true))后,TextureRegion的UV坐标把上下颠倒了,可NinePatch还是按照原始的20px去计算,这时候实际对应的区域要么超出了翻转后的TextureRegion范围,要么完全不是你预期的部分,最终导致背景无法正常显示。
解决办法
有两种靠谱的方式可以解决这个问题:
1. 先创建NinePatch,再翻转Drawable(推荐)
不要直接翻转TextureRegion,而是先基于原始TextureRegion创建好NinePatch,然后通过NinePatchDrawable自带的setFlip()方法来实现翻转:
// 先基于原始纹理创建NinePatch,保证拉伸区域参数正确 TextureRegion region = new TextureRegion(new Texture("path to the file")); NinePatch patch = new NinePatch(region, left, right, up, down); NinePatchDrawable drawable = new NinePatchDrawable(patch); // 在Drawable层面执行翻转操作,不影响NinePatch的区域计算 drawable.setFlip(false, true); Table table = new Table(); table.setBackground(drawable); table.add(someLabel);
这种方式既能保持NinePatch内部的拉伸逻辑正确,又能实现你想要的翻转效果,是最稳妥的方案。
2. 手动调整NinePatch参数适配翻转后的区域
如果你一定要先翻转TextureRegion,那需要重新计算left/right/up/down参数来适配翻转后的坐标。比如垂直翻转的情况下,原来的up要替换成原始纹理高度 - down,down替换成原始纹理高度 - up:
Texture texture = new Texture("path to the file"); TextureRegion region = new TextureRegion(texture); region.flip(false, true); // 根据翻转后的坐标重新计算NinePatch参数 int originalHeight = texture.getHeight(); int newUp = originalHeight - down; int newDown = originalHeight - up; NinePatch patch = new NinePatch(region, left, right, newUp, newDown); NinePatchDrawable drawable = new NinePatchDrawable(patch); Table table = new Table(); table.setBackground(drawable); table.add(someLabel);
这种方式需要手动映射参数,相对繁琐,所以更推荐第一种方法。
内容的提问来源于stack exchange,提问作者MarkDanghyan

