Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Input detection for a Group with overlapping transparent Images

Tags:

libgdx

I use a Group to store some Images and draw them to a SpriteBatch. Now I want to detect which Image has been clicked. For this reason I add an InputListener to the Group to get an event on touch down. The incoming InputEvent got an method (getTarget) that returns an reference to the clicked Actor.

If I click on a transparent area of an Actor I want to ignore the incoming event. And if there is an Actor behind it I want to use this instead. I thought about something like this:

    myGroup.addListener(new InputListener() {
        @Override
        public boolean touchDown(InputEvent event, float x, float y, int pointer, int button) {
            Actor targetActor = event.getTarget();
            // is the touched pixel transparent: return false
            // else: use targetActor to handle the event and return true
        };
    });

Is this the right way to do it? I thought returning false for the method touchDown would continue propagation for the event and let me also receive touchDown events for other Actors at the same position. But this seems to be a misunderstanding...

UPDATE

P.T.s answer solves the problem of getting the right Event. Now I have got the problem to detect if the hit pixel is transparent. It seems to me that I need the Image as a Pixmap to get access. But I do not know how to convert an Image to a Pixmap. I also wonder if this is a good solution in terms of performance and memory usage..

like image 804
Luca Hofmann Avatar asked May 25 '13 11:05

Luca Hofmann


1 Answers

I think you want to override the Actor.hit() method. See the scene2d Hit Detection wiki.

To do this, subclass Image, and put your hit specialization in there. Something like:

public Actor hit(float x, float y, boolean touchable) {
  Actor result = super.hit(x, y, touchable);
  if (result != null) { // x,y is within bounding box of this Actor
     // Test if actor is really hit (do nothing) or it was missed (set result = null)
  }
  return result;
}

I believe you cannot accomplish this within the touchDown listener because the Stage will have skipped the Actors "behind" this one (only "parent" actors will get the touchDown event if you return false here).

like image 115
P.T. Avatar answered Sep 27 '22 22:09

P.T.