Reputation: 6018
I'm trying to make an Actor
handle both click and key down events. I initialized the actor (in this case, an Image
) as following:
stage = new Stage();
texture = new Texture("badlogic.jpg");
Image image = new Image(texture);
image.addListener(new ClickListener() {
@Override
public void clicked(InputEvent event, float x, float y) {
Gdx.app.log("Image ClickListener", "clicked");
}
@Override
public boolean keyDown(InputEvent event, int keycode) {
Gdx.app.log("Image ClickListener", "keyDown. keycode=" + keycode);
return true;
}
});
stage.addActor(image);
Gdx.input.setInputProcessor(stage);
When I click on image
, the clicked event is fired as expected, i.e., I see the respective log. However, no matter what key I press, the key down event does not fire. My question is: Why? Can't an Actor be able to handle both click and key down events?
Upvotes: 1
Views: 1428
Reputation: 9045
Create a custom class that extends the Actor
class and implements the InputProcessor
interface.
When you set up your game, use an InputMultiplexer
:
InputMultiplexer inputMulti = new InputMultiplexer(stage);
Gdx.input.setInputProcessor( inputMulti );
Then, in the constructor of your custom class, you can add the instance being created to the multiplexer as follows:
((InputMultiplexer)Gdx.input.getInputProcessor()).addProcessor(this);
Handling key input functionality then becomes simpler: instead of using the addListener
method and creating an anonymous inner class that extends ClickListener
etc. etc., you can just use the InputProcessor
methods, for example:
public boolean keyDown(int keycode)
{
if (keycode == Keys.SPACE)
{
// do something
}
return false;
}
This also avoids the need to set keyboard focus on the actor, which might not generalize well if you have multiple actors that need to process keyboard input.
However, one caveat to this approach is that any actor configured as an input processor will process all input events now, including touch events that do not overlap the actor, and this behavior may be undesired and/or confusing.
Upvotes: 1
Reputation: 13571
By default you should rather attach keyboard listener to the stage since the stage has keyboard focus on it so it should be something like
stage.addListener(new InputListener()
{
@Override
public boolean keyDown(InputEvent event, int keycode)
{
Gdx.app.log("Image ClickListener", "keyDown. keycode=" + keycode);
return true;
}
});
If you want to change focus to be on the actor you can do this by using Stage method setKeyboardFocus(Actor actor). It should be something like:
image.addListener(new ClickListener()
{
@Override
public void clicked(InputEvent event, float x, float y) {
Gdx.app.log("Image ClickListener", "clicked");
}
@Override
public boolean keyDown(InputEvent event, int keycode) {
Gdx.app.log("Image ClickListener", "keyDown. keycode=" + keycode);
return true;
}
});
stage.setKeyboardFocus(image);
Upvotes: 4