LibGDX Tiled получает свойство объекта при столкновении

Я работаю над игрой в LibGDX и настроил карту с помощью Tiled. Я добавил настраиваемое свойство String к объектам в определенном слое, чтобы получить дополнительную информацию о том, какой объект он представляет.

У меня настроен ContactListener, который вызывает метод в абстрактном классе объекта карты. Слушатель выглядит так:

@Override
public void beginContact(Contact contact) {

    Fixture fixtureA = contact.getFixtureA();
    Fixture fixtureB = contact.getFixtureB();

    if (fixtureA.getUserData() == "player" || fixtureB.getUserData() == "player") {
        // Get either fixture A or B, depending on which of them is the player fixture
        Fixture player = fixtureA.getUserData() == "player" ? fixtureA : fixtureB;
        // Get the colliding object, depending on which of them is the player fixture
        Fixture collidedObject = player == fixtureA ? fixtureB : fixtureA;

        // Determine what kind of object the player collided with and trigger the respectable method
        if (collidedObject.getUserData() instanceof InteractiveMapTileObject) {
            ((InteractiveMapTileObject) collidedObject.getUserData()).onPlayerBeginContact();
        } else if (collidedObject.getUserData() instanceof Enemy) {
            ((Enemy) collidedObject.getUserData()).onPlayerBeginContact();
        }
    }
}

Когда игрок попадает в объект экземпляра InteractiveMapTileObject, вызывается метод onPlayerBeginContact (), который выглядит следующим образом:

@Override
public void onPlayerBeginContact() {
    MapObjects objects = playScreen.getMap().getLayers().get("weapon").getObjects();
    for (MapObject object : objects) {
        if (object.getProperties().containsKey("weapon_name")) {
            String weaponName = object.getProperties().get("weapon_name", String.class);
            Gdx.app.log("Picked up weapon", weaponName);
        }
    }
}

Здесь я получаю объекты слоя «оружие» на карте, а затем просматриваю их, чтобы найти правильное свойство и его значение. Это прекрасно работает и так.

Проблема теперь в том, что у меня, очевидно, есть несколько объектов в слое и, следовательно, несколько объектов MapObject. Мне нужен способ идентифицировать объект, с которым игрок столкнулся, а затем получить его свойство.

Можно ли это сделать с помощью ContactListener или мне нужно реализовать что-то еще? Я уже просмотрел массу сообщений, но мне не повезло.


person Johannes Mols    schedule 12.11.2017    source источник


Ответы (2)


Я думаю, вместо того, чтобы получать имя оружия из MapObject, возьмите его из класса Weapon.

Каждое оружие может унаследовать от InteractiveTileMapObject. Когда игрок сталкивается с приспособлением, вы можете получить ссылку из пользовательских данных и, используя ссылку, получить имя оружия.

Надеюсь, этот ответ помог вам, и если у вас есть дополнительные вопросы, не стесняйтесь оставлять комментарии ниже!

person Micheal O'Dwyer    schedule 12.11.2017
comment
Я попытался оценить пользовательские данные при столкновении с объектом, но я не могу определить свойства столкнувшегося объекта, я могу получить доступ только к свойствам карт и тому подобному. Вот снимок экрана с пользовательскими данными: imgur.com/a/GxJ2R - person Johannes Mols; 12.11.2017

Я решил свою проблему, написав собственный метод в моем абстрактном классе для проверки пересечения каждого объекта в определенном объектном слое.

protected MapObject getCellProperties(int layerIndex) {
    MapObjects mapObjects = map.getLayers().get(layerIndex).getObjects();

    for (MapObject mapObject : mapObjects) {
        MapProperties mapProperties = mapObject.getProperties();

        float width, height, x, y;
        Rectangle objectRectangle = new Rectangle();
        Rectangle playerRectangle = new Rectangle();

        if (mapProperties.containsKey("width") && mapProperties.containsKey("height") && mapProperties.containsKey("x") && mapProperties.containsKey("y")) {
            width = (float) mapProperties.get("width");
            height = (float) mapProperties.get("height");
            x = (float) mapProperties.get("x");
            y = (float) mapProperties.get("y");
            objectRectangle.set(x, y, width, height);
        }

        playerRectangle.set(
                playScreen.getPlayer().getX() * MainGameClass.PPM,
                playScreen.getPlayer().getY() * MainGameClass.PPM,
                playScreen.getPlayer().getWidth() * MainGameClass.PPM,
                playScreen.getPlayer().getHeight() * MainGameClass.PPM
        );

        // If the player rectangle and the object rectangle is colliding, return the object
        if (Intersector.overlaps(objectRectangle, playerRectangle)) {
            return mapObject;
        }
    }

    // If no colliding object was found in that layer
    return null;
}

Это, наверное, не лучшее решение, но прекрасно работает.

person Johannes Mols    schedule 13.11.2017