Actors in LibGDX have a z-order, which is basically just their position in the Stage’s children list. Actor’s methods toFront() and toBack() call Actor.setZIndex() which in turn move the actor within its parent group’s children list. Actors with lower z index are drawn below actors with higher z index.
Now the question is, how can I figure out if some actor is in front of another actor?
LibGDX doesn’t offer a direct way of doing this, so we need to do it manually. Here’s the code:
/**
* Returns true in case actor 'a' is in front of actor 'b' in given stage.
* Note that both actors must be in given stage (and hence have a common ancestor).
* @param a is actor a in front of actor b?
* @param b is actor a in front of actor b?
* @param stage stage in which both given actors reside
* @return true in case 'a' is in front of 'b'
* @throws IllegalArgumentException in case given actors don't have common ancestor
*/
public static boolean isActorInFrontOfAnother(Actor a, Actor b, Stage stage) {
if (a == b) // special case
return false;
List<Actor> g1 = new ArrayList<>(); // genealogy of actor a. First item in the list (index 0) is actor a, then his parent, then his parent's parent, and so on, until stage's root table
List<Actor> g2 = new ArrayList<>(); // same as g1, but for actor b
Actor root = stage.getRoot();
g1.add(a);
Actor node = a;
while (node.getParent() != root) {
g1.add(node.getParent());
node = node.getParent();
}
g1.add(root);
g2.add(b);
node = b;
while (node.getParent() != root) {
g2.add(node.getParent());
node = node.getParent();
}
g2.add(root);
// now find first common parent:
Actor p1, p2; // (grand*)parents of actors a and b
int i = g1.size()-1;
int j = g2.size()-1;
while (true) {
p1 = g1.get(i);
p2 = g2.get(j);
if (p1 != p2)
break;
i--;
j--;
if (i < 0 || j < 0)
throw new IllegalArgumentException("Given actors don't have common ancestor");
}
// Actors p1 and p2 are both children of last common parent of a and b. Actors a and b derive from p1 and p2 (p1 and p2 could be a and b themselves too, if there are no other parents in between).
return p1.getZIndex() > p2.getZIndex();
}