英文:
LibGDX 9 patch image over a tilable background
问题
我正在使用LibGDX UI组件来显示游戏的用户界面。
我想在我的菜单背后显示一个有边框的大理石背景。为此,我有一个带有边框的九宫格图像和一个大理石背景图像。
我尝试在我的菜单中同时使用它们,菜单由包含表格的滚动窗格组成。
因此,我将九宫格边框定义为滚动窗格的背景:
com.badlogic.gdx.scenes.scene2d.ui.ScrollPane$ScrollPaneStyle: {
default: { ..., background: frame }
}
然后将(大)大理石背景添加到我的表格:
table.setBackground(skin.getTiledDrawable("big-marble-texture"));
然而,看起来边框在大理石背景周围,而不是它的一部分:
我不能只是将大理石纹理作为九宫格的一部分:我希它可以平铺,而不是按菜单尺寸缩放(我尝试过,效果很差)。
我还尝试过直接在舞台上显示边框,它可以工作,但使用起来真的很痛苦,尤其是对于像工具提示或移动卡片等动态UI。
在libgdx UI组件中,有什么推荐的做法呢?
英文:
I'm using LibGDX UI components to display the UI of my game.
I want to show a framed marble background behind my menus. For this I have a nine-patch image with the frame and a marble background image.
It tried to use both in my menu, composed of a ScrollPane containing a Table.
So I defined the 9 patch frame as the ScrollPane background:
com.badlogic.gdx.scenes.scene2d.ui.ScrollPane$ScrollPaneStyle: {
default: { ..., background: frame }
}
And add the (big) marble background to my table:
table.setBackground(skin.getTiledDrawable("big-marble-texture"));
However it looks like the frame is around the marble background, not part of it:
I cannot just make the marble texture part of the 9 patch: I want it to be tiled, not scaled to the menu dimension (I tried, it looks horrible).
I also tried to display the frame directly in the Stage on top of the menu, it works but then the code is really painful to use, especially with dynamic UI like tooltips or moving cards.
What is the recommended way of doing this in libgdx UI components?
答案1
得分: 2
我不确定解决这个问题的推荐方法是什么,但其中一种方法是创建一个类,该类是TiledDrawable
和NinePatch
的组合,然后让该类扩展BaseDrawable
。
这样,您可以重写draw
方法,首先将背景绘制为TiledDrawable
(根据NinePatch
的插图进行偏移),然后将NinePatch
绘制为边框。
例如:
package com.bornander.sandbox;
import com.badlogic.gdx.graphics.Texture;
import com.badlogic.gdx.graphics.g2d.Batch;
import com.badlogic.gdx.graphics.g2d.NinePatch;
import com.badlogic.gdx.graphics.g2d.TextureRegion;
import com.badlogic.gdx.scenes.scene2d.utils.BaseDrawable;
import com.badlogic.gdx.scenes.scene2d.utils.TiledDrawable;
import com.badlogic.gdx.scenes.scene2d.utils.TransformDrawable;
public class BorderedTiledDrawable extends BaseDrawable implements TransformDrawable {
private TiledDrawable region;
private NinePatch patch;
private int left;
private int top;
private int right;
private int bottom;
public BorderedTiledDrawable(Texture background, Texture border, int left, int top, int right, int bottom) {
region = new TiledDrawable(new TextureRegion(background));
this.patch = new NinePatch(border, left, top, right, bottom);
this.left = left - 1;
this.top = top - 1;
this.right = right - 1;
this.bottom = bottom - 1;
setMinWidth(patch.getTotalWidth());
setMinHeight(patch.getTotalHeight());
setTopHeight(patch.getPadTop());
setRightWidth(patch.getPadRight());
setBottomHeight(patch.getPadBottom());
setLeftWidth(patch.getPadLeft());
}
@Override
public void draw(Batch batch, float x, float y, float originX, float originY, float width, float height, float scaleX, float scaleY, float rotation) {
region.draw(batch, x, y, originX, originY, width, height, scaleX, scaleY, rotation);
patch.draw(batch, x, y, originX, originY, width, height, scaleX, scaleY, rotation);
}
@Override
public void draw(Batch batch, float x, float y, float width, float height) {
region.draw(batch, x + left, y + top, width - (left + right), height - (top + bottom));
patch.draw(batch, x, y, width, height);
}
}
其效果如下:
(图片已省略)
如果您的九宫格图案具有非常圆润的角落,则其效果不会完全正确,但这也很容易进行微调。
英文:
I am not sure what the recommended way of solving this is but one way is to create a class that is a composite of a TiledDrawable
and a NinePatch
and let that class extend BaseDrawable
.
That way you can override the draw
method to first draw the background as a TiledDrawable
(offset to account for the insets of the NinePatch
) and then draw the NinePatch
as the border.
For example:
package com.bornander.sandbox;
import com.badlogic.gdx.graphics.Texture;
import com.badlogic.gdx.graphics.g2d.Batch;
import com.badlogic.gdx.graphics.g2d.NinePatch;
import com.badlogic.gdx.graphics.g2d.TextureRegion;
import com.badlogic.gdx.scenes.scene2d.utils.BaseDrawable;
import com.badlogic.gdx.scenes.scene2d.utils.TiledDrawable;
import com.badlogic.gdx.scenes.scene2d.utils.TransformDrawable;
public class BorderedTiledDrawable extends BaseDrawable implements TransformDrawable {
private TiledDrawable region;
private NinePatch patch;
private int left;
private int top;
private int right;
private int bottom;
public BorderedTiledDrawable(Texture background, Texture border, int left, int top, int right, int bottom) {
region = new TiledDrawable(new TextureRegion(background));
this.patch = new NinePatch(border, left, top, right, bottom);
this.left = left - 1;
this.top = top - 1;
this.right = right - 1;
this.bottom = bottom - 1;
setMinWidth(patch.getTotalWidth());
setMinHeight(patch.getTotalHeight());
setTopHeight(patch.getPadTop());
setRightWidth(patch.getPadRight());
setBottomHeight(patch.getPadBottom());
setLeftWidth(patch.getPadLeft());
}
@Override
public void draw(Batch batch, float x, float y, float originX, float originY, float width, float height, float scaleX, float scaleY, float rotation) {
region.draw(batch, x, y, originX, originY, width, height, scaleX, scaleY, rotation);
patch.draw(batch, x, y, originX, originY, width, height, scaleX, scaleY, rotation);
}
@Override
public void draw(Batch batch, float x, float y, float width, float height) {
region.draw(batch, x + left, y + top, width - (left + right), height - (top + bottom));
patch.draw(batch, x, y, width, height);
}
}
Which looks like this:
It does't fully work if your nine-patch has very rounded corners but that is also easy to tweak.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论