How can I add click listeners for the tiles from tiled map so that when you select a tile with the mouse it becomes highlighted?
That's not supported directly by libGDX as the TiledMap stuff is only for rendering.
You could easily create a Stage
though, which will act as some kind of overlay-input-layer for your TiledMap. Just create an Actor
for each tile which has the same size as position as that tile. Then you are able to add EventListener
s to those actors to be able to recognize things like clicks on those actors.
Those actors should keep a reference to their "origin", namely TiledMapTileLayer.Cell
. So you are able to go back from the actor to the cell anytime when processing those events.
The following shows how you might do it:
This Actor is responsible to catch the events and keep the information about the tile it's based on:
public class TiledMapActor extends Actor {
private TiledMap tiledMap;
private TiledMapTileLayer tiledLayer;
private TiledMapTileLayer.Cell cell;
public TiledMapActor(TiledMap tiledMap, TiledMapTileLayer tiledLayer, TiledMapTileLayer.Cell cell) {
this.tiledMap = tiledMap;
this.tiledLayer = tiledLayer;
this.cell = cell;
}
}
This little listener can be attached to one of those actors and will do any kind of logic:
public class TiledMapClickListener extends ClickListener {
private TiledMapActor actor;
public TiledMapClickListener(TiledMapActor actor) {
this.actor = actor;
}
@Override
public void clicked(InputEvent event, float x, float y) {
System.out.println(actor.cell + " has been clicked.");
}
}
The following class actually creates the actors from a given map and wires them to the listeners:
public class TiledMapStage extends Stage {
private TiledMap tiledMap;
public TiledMapStage(TiledMap tiledMap) {
this.tiledMap = tiledMap;
for (MapLayer layer : tiledMap.getLayers()) {
TiledMapTileLayer tiledLayer = (TiledMapTileLayer)layer;
createActorsForLayer(tiledLayer);
}
}
private void createActorsForLayer(TiledMapTileLayer tiledLayer) {
for (int x = 0; x < tiledLayer.getWidth(); x++) {
for (int y = 0; y < tiledLayer.getHeight(); y++) {
TiledMapTileLayer.Cell cell = tiledLayer.getCell(x, y);
TiledMapActor actor = new TiledMapActor(tiledMap, tiledLayer, cell);
actor.setBounds(x * tiledLayer.getTileWidth(), y * tiledLayer.getTileHeight(), tiledLayer.getTileWidth(),
tiledLayer.getTileHeight());
addActor(actor);
EventListener eventListener = new TiledMapClickListener(actor);
actor.addListener(eventListener);
}
}
}
}
Now the TiledMapStage
will do all work for you. All you need to do is the following:
Stage stage = new TiledMapStage(tiledMap);
Gdx.input.setInputProcessor(stage);
And in render(...) you need to call stage.act()
. Remember to use the same Viewport
for the stage as you are using to render the TiledMap. Otherwise the input and your rendered map won't be aligned.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With