I have this code snippet located in a Group:
addActor(getActiveLineSegment());
getActiveLineSegment().addListener(new InputListener(){
@Override
public void enter(InputEvent event, float x, float y, int pointer, Actor fromActor){
System.out.println("Enter");
}
@Override
public void exit(InputEvent event, float x, float y, int pointer, Actor toActor){
System.out.println("Exit");
}
@Override
public boolean touchDown (InputEvent event, float x, float y, int pointer, int button) {
return true;
}
});
Some of the actors bounds may overlap which seems to cause issues with the enter/exit events detection. Only the most recent actor of the overlapping actors detects the event probably because its Z value is higher. Is there a way I can fire the enter/exit events on all actors instead of just the one on top?
The behaviour you described is intentional. For each pointer and in one frame, the enter event can be fired only by one actor under the pointer. Same for exit events. That's how Stage
is desinged, and seems not trivial to change this behavior.
By the way, touchDown()
returning true or false has nothing to do with this.
I can think of a possible workaround, it's a bit messy, but here is the general idea:
1) Add another InputProcessor
before your Stage
, using InputMultiplexer
2) Using that processor, track coordinates for each touched pointer. On touch you register a pointer, on touchDrag and/or mouseMove you update it, on touchUp - unregister it.
3) Each frame, check for every activeLineSegment if it's under any touched pointer. For that you need to convert screen coords for each pointer to local coords of activeLineSegments' parent, using Actor.screenToLocalCoordinates (Vector2)
.
If an activeLineSegment wasn't under a pointer in previous frame, and it is in a current frame, then you can treat this situation as enter event. And if the activeLineSegment was under the pointer previously, and in the current frame is not (or the pointer was removed) then it's an exit event.