LibGDX:как сделать плитки карты кликабельными?

Как добавить прослушиватели щелчка для плиток из плиточной Карты, чтобы при выборе плитки мышью она становилась выделенной?

1 ответов


это не поддерживается напрямую и libGDX как TiledMap вещи только для рендеринга.

вы можете легко создать Stage хотя, который будет действовать как своего рода оверлей-входной слой для вашего TiledMap. Просто создайте Actor для каждой плитки которая имеет такой же размер как положение как эта плитка. Тогда вы можете добавить EventListeners для этих актеров, чтобы иметь возможность распознавать такие вещи, как щелчки по этим актерам.

эти актеры должны сохранить ссылку на их "происхождение", а именно TiledMapTileLayer.Cell. Таким образом, вы можете вернуться от актера к ячейке в любое время при обработке этих событий.

ниже показано, как вы можете это сделать:

Этот актер отвечает, Чтобы поймать события и сохранить информацию о плитке он основан на:

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.");
    }
}

следующий класс фактически создает актеров с данной карты и передает их слушателям:

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(). Не забудьте использовать то же самое Viewport для этапа, как вы используете для рендеринга TiledMap. В противном случае вход и отображаемая карта не будут выровнены.