Java 覆盖图纸订单场景2D的阶段

Java 覆盖图纸订单场景2D的阶段,java,libgdx,scene2d,scenegraph,Java,Libgdx,Scene2d,Scenegraph,在libgdx中,您将看到一个复杂的Scene2D图,其中包含多个组和演员。您希望用户选择一些角色,并在最后绘制这些角色,以便它们在任何其他角色的顶部显示为焦点 我想在这个阶段重复两次。第一次绘制未选定的参与者,第二次绘制选定的参与者。然而,我看不到任何“好”的方法来实施这种行为 我更喜欢干净的选项。我不想仅仅为了这个小小的添加而复制整个方法实现 什么不起作用: 演员的toFront方法只适用于其兄弟姐妹。 在舞台上交换演员的位置:这会修改演员的变换。 要考虑的场景:您有一个根,其中有一个组gA

在libgdx中,您将看到一个复杂的Scene2D图,其中包含多个组和演员。您希望用户选择一些角色,并在最后绘制这些角色,以便它们在任何其他角色的顶部显示为焦点

我想在这个阶段重复两次。第一次绘制未选定的参与者,第二次绘制选定的参与者。然而,我看不到任何“好”的方法来实施这种行为

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

什么不起作用:

演员的toFront方法只适用于其兄弟姐妹。 在舞台上交换演员的位置:这会修改演员的变换。 要考虑的场景:您有一个根,其中有一个组gA和一个组gB。gA组包含两个图像iA1和iA2。组gB包含一个图像iB。假设组gA首先添加到阶段,且图像iA1与iB重叠;现在,您需要选择iA1并使其显示在iB上。我不想只调用gA.toFront;这将把整个组gA放在前面,这意味着iA2也放在前面。将iA2放在前面会产生不希望的效果,即隐藏组gB内的部分图像


有两种解决方案-

1-停止使用[多个]组。很糟糕,但这可能是更容易的选择。如果查看渲染/绘制是如何完成的,则从阶段的根组开始,获取其子级并进行渲染。对于这些子对象中的每个子对象,如果它们是一个组,则渲染该组子对象。ZIndex只不过是一组孩子的顺序。如果你看演员的setZIndex,你就会明白为什么toFront或setZIndex只影响兄弟姐妹

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方法,以便根据您选择的不同顺序进行绘制。您可能需要合并Group.drawChildren方法中的许多功能


TLDR;在LibGDX中实现事物的方式-组是一个层。如果不需要图层,请更改组的功能或停止使用组。

您可以通过覆盖父对象上的绘图来解决此问题:

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);

有关某些想法,请参阅。这些想法只适用于团队中的所有兄弟姐妹。不在场景图中不同分支上多个深度上的演员/组之间。如果设置演员的z索引,则使用toFront或toBack会更改该演员的z索引并对演员列表进行排序。最后将绘制z指数高的演员,首先绘制z指数低的演员,然后绘制后面的演员。如果在select方法中调用actor.toFront或以任何方式调用它,则此actor将在最后一次渲染。在取消选择中,您可以调用toBack。这适用于Group to,因为Group是一个Actor子类。这不是一个100%有效的东西,但在这种情况下,这应该足够了。@Vjeetje它确实适用于场景图中的组。因为一个团体也是一个演员,所以你可以将它进行同样的比较。只需给团队适当的深度。在这种情况下,组的兄弟姐妹应具有相同的深度。否则它就不起作用了,因为你不能让团队在舞台内的不同时间抽签。只需从我推荐的组中调用.draw来添加insertionsort而不是集合排序。对于一个排序紧密的列表来说,这要快得多。您的列表不会有太多变化,我想可能我对此不清楚,但这些想法没有考虑以下情况:您有一个根,有一个组gA和一个组gB。gA组包含两个图像iA1和iA2。组gB包含一个图像iB。假设组gA首先添加到阶段,且图像iA1与iB重叠;现在,您希望选择iA1并使其显示在iB上。您的建议将把整个组gA放在前面,这意味着iA2也放在前面。放置iA2会产生不期望的效果。