1
votes

I tried use InputListener with Actor, but it doesn't work. I really don't know why. I found many information about it and saw official documentation but not one of all didn't help me.

My log messages are not shown when I touch the sprite. But if I use the global input processor (for whole screen) it works fine, but I want to add only one listener only for actor.

What am I doing wrong?

public class GameScreen implements Screen {
    final Launch launch;
    Texture texture;
    Stage stage;


    public GameScreen(Launch launch) {
        Gdx.app.setLogLevel(Application.LOG_DEBUG);
        this.launch = launch;
        texture = new Texture("hero.png");
        stage = new Stage();
        Hero hero = new Hero();
        hero.addListener(new HeroListener());
        stage.addActor(hero);
        Gdx.input.setInputProcessor(stage);

    }

    @Override
    public void render(float delta) {
        Gdx.gl.glClearColor(0, 0, 0.2f, 1);
        Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT);
        stage.draw();
        stage.act(Gdx.graphics.getDeltaTime());

    }

    @Override
    public void resize(int width, int height) {
    }

    @Override
    public void show() {
    }

    @Override
    public void hide() {
    }

    @Override
    public void pause() {
    }

    @Override
    public void resume() {
    }

    @Override
    public void dispose() {
        stage.dispose();
        texture.dispose();
    }

    private class Hero extends Actor {

        @Override
        public boolean addListener(EventListener listener) {
            Gdx.app.debug("MyTag", "my debug message");
            return super.addListener(listener);
        }

        @Override
        public void draw(Batch batch, float parentAlpha) {
            batch.draw(texture, 0, 0, 500, 500);
        }
    }

    private class HeroListener extends InputListener {
        @Override
        public boolean touchDown(InputEvent event, float x, float y, int pointer, int button) {
            Gdx.app.debug("MyTag", "touch down");
            return super.touchDown(event, x, y, pointer, button);
        }

        @Override
        public void touchUp(InputEvent event, float x, float y, int pointer, int button) {
            Gdx.app.debug("MyTag", "touch up");
            super.touchUp(event, x, y, pointer, button);
        }
    }
}
1

1 Answers

3
votes

The problem is that you are not giving any size or position to your actor. InputListener work for events whitin the bounds of the Actor. If you do not define any size to your Actor, it won't ever receive an event.

Hero hero = new Hero();
hero.addListener(new HeroListener());

hero.setBounds(0, 0, 500, 500);

stage.addActor(hero);

That should make your InputListener listen to touchDown/Up events in the (0, 0), (500, 500) bounds.

Also, it's conveninent because you can use those bounds when drawing after:

@Override
public void draw(Batch batch, float parentAlpha) {
    batch.draw(texture, getX(), getY(), getWidth(), getHeight());
}