覆盖绘图顺序scene2D的舞台
Posted
技术标签:
【中文标题】覆盖绘图顺序scene2D的舞台【英文标题】:overriding drawing order scene2D's stage 【发布时间】:2014-03-17 08:27:28 【问题描述】:在libgdx
中为您提供了一个复杂的Scene2D
图,其中包含多个Group's
和Actor'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
【问题讨论】:
见***.com/questions/16129903/… 了解一些想法 这些想法只适用于组内的所有兄弟姐妹。不在场景图中不同分支上多个深度的演员/组之间。 如果设置Actor
的z 索引,通过使用toFront() 或toBack() 会更改Actor
的z-Index 并对Actor
列表进行排序。 Actor
s 具有高 z 索引的最后会绘制,Actor
s 具有低 z 索引将首先绘制,以此类推。如果您在 select()
方法中调用 actor.toFront() 或者无论如何调用它,这个 Actor
将在最后呈现。在deselect()
,您可以致电toBack()
。这适用于Group
到,因为Group
是Actor
子类。这不是一个 100% 的工作,但在这种情况下,这应该足够了。
@Vjeetje 它确实适用于场景图中的组。由于Group
也是Actor
,因此您可以将其进行比较。只需为Group
提供正确的深度。在这种情况下,该组的兄弟姐妹应该具有相同的深度。否则它不会起作用,因为你不能让组在舞台内的不同时间绘制。 (只需从集团中调用.draw
)我建议添加一个插入排序而不是集合排序。对于紧密排序的列表,它要快得多。 (我认为你的名单不会有太大变化)
也许我并不清楚这一点,但这些想法没有考虑到以下情况:你有一个具有组 gA 和组 gB 的根。 gA 组包含两个图像 iA1 和 iA2。 gB 组包含一个图像 iB。假设 gA 组首先添加到阶段,并且图像 iA1 与 iB 重叠;现在您要选择 iA1 并使其出现在 iB 上。您的建议会将整个 gA 组放在前面,这意味着 iA2 也放在前面。放置 iA2 会产生不良影响。
【参考方案1】:
有两种解决方案-
1 - 停止使用 [多个] 组。糟透了,但这可能是更容易的选择。如果您查看渲染/绘图是如何完成的,您可以从舞台的根组开始并获取其子级并渲染它们。对于这些孩子中的每一个,如果它们是一个组,则呈现该组的孩子。 ZIndex 只不过是一个组内的孩子的顺序。如果您查看 Actor 的 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
方法替换为 draw
。您可能需要整合Group.drawChildren
方法中的许多功能。
TLDR; LibGDX 中的实现方式 - 组是一个层。如果您不想要图层,请更改组的功能或停止使用组。
【讨论】:
【参考方案2】:您可以通过覆盖父级上的 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);
【讨论】:
以上是关于覆盖绘图顺序scene2D的舞台的主要内容,如果未能解决你的问题,请参考以下文章