如何在平铺 map 中为平铺 map 添加点击侦听器,以便在用鼠标选择平铺 map 时将其突出显示?

最佳答案

libGDX不直接支持该功能,因为TiledMap内容仅用于渲染。

不过,您可以轻松创建一个Stage,它将充当TiledMap的某种叠加输入层。只需为每个图块创建一个Actor,该图的大小与该图块的位置相同。然后,您可以向这些参与者添加EventListener,从而能够识别诸如点击这些参与者的事情。

这些参与者应保留对其“起源”的引用,即TiledMapTileLayer.Cell。因此,在处理这些事件时,您可以随时从角色返回到单元。

下面显示了如何执行此操作:

该Actor负责捕获事件并根据以下内容保留有关其图块的信息:

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;
    }

}

这个小侦听器可以附加到其中一个参与者上,并且可以执行任何逻辑:
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.");
    }
}

下面的类实际上是根据给定的映射创建actor并将其连接到侦听器:
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);
            }
        }
    }
}

现在,TiledMapStage将为您完成所有工作。您需要做的只是以下几点:
Stage stage = new TiledMapStage(tiledMap);
Gdx.input.setInputProcessor(stage);

在render(...)中,您需要调用stage.act()。请记住,在渲染TiledMap时,请在舞台上使用相同的Viewport。否则,输入和渲染的 map 将无法对齐。

07-27 23:17