覆盖绘制顺序scene2D的阶段

时间:2014-02-17 21:08:42

标签: java libgdx scene2d scenegraph

Scene2D为您提供了一个复杂的libgdx图表,其中包含多个Group'sActor's。您希望用户选择一些Actors并在最后绘制这些内容,以便它们显示在任何其他Actors之上。

我想迭代Stage两次。第一次绘制未选中的Actors时,第二次绘制选定的actors。但是,我没有看到任何“好”的方式来强制执行此行为。

我更喜欢干净的选择。我不想仅仅为了这个小小的添加而复制整个方法实现。

什么行不通:

  • Actor's toFront()方法仅适用于其兄弟姐妹。
  • 在舞台中交换Actor's的地方:这会修改Actors所拥有的转化。

要考虑的情景:您有一个Root,其中一个 gA 组和一个 gB 组。 Group gA 包含两个图像 iA1 iA2 Group gB 包含一个图像 iB 。鉴于首先将Group gA 添加到舞台,并且该图像 iA1 iB 重叠;现在您要选择 iA1 并使其显示在 iB 上。我不想只调用 gA.toFront();这会将整个Group gA 放在前面,这意味着 iA2 也会放在前面。将 iA2 置于前面会导致隐藏Group gB 内部图像部分的不良影响

enter image description here

2 个答案:

答案 0 :(得分:1)

有两种解决方案 -

1 - 停止使用[多个]组。很糟糕,但这可能是更容易的选择。如果您查看渲染/绘图是如何完成的,您可以从舞台的根组开始并获取其子项并渲染它们。对于这些孩子中的每一个,如果他们是一个组,则渲染该组孩子。 ZIndex 只不过是群组中孩子的顺序。如果您查看Actor setZIndex,您可以看到toFrontsetZIndex仅影响兄弟姐妹的原因。

public void setZIndex (int index) {
    if (index < 0) 
        throw new IllegalArgumentException("ZIndex cannot be < 0.");

    Group parent = this.parent;
    if (parent == null) 
        return;

    Array<Actor> children = parent.getChildren();
    if (children.size == 1) 
        return;

    if (!children.removeValue(this, true)) 
        return;

    if (index >= children.size)
        children.add(this);
    else
        children.insert(index, this);
}

2 - 唯一的另一种选择是改变所有演员的绘画顺序。您必须扩展Stage并根据您选择的不同顺序将draw方法替换为draw。您可能必须使用Group.drawChildren方法中的许多功能。

TLDR;在 LibGDX 中实现的方式 - 组是一个层。如果您不想要图层,则可以更改组执行的操作或停止使用组。

答案 1 :(得分:0)

您可以通过在父级上覆盖draw来解决此问题:

Group parent = new Group() {
    // Do not render the child as we will render it later
    @Override
    protected void drawChildren(Batch batch, float parentAlpha) {
        child.setVisible(false);
        super.drawChildren(batch, parentAlpha);
        child.setVisible(true);
    }

    // Render the child after the draw method so it's always on top
    @Override
    public void draw(Batch batch, float parentAlpha) {
        super.draw(batch, parentAlpha);
        child.draw(batch, parentAlpha);
    }
};

Group child = new Group();
parent.addActor(child);