LibGDX: How to make tiled map tiles clickable?

狂风中的少年 提交于 2019-11-26 16:32:18

问题


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?


回答1:


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 EventListeners 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.



来源:https://stackoverflow.com/questions/24080272/libgdx-how-to-make-tiled-map-tiles-clickable

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!