1

I'm working on a game in LibGDX, and have a map set up with Tiled. I added a custom String property to objects in a specific layer to get further information, what object it represents.

I have a ContactListener set up, that calls a method in the abstract class of the map object. The listener looks like this:

@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();
        }
    }
}

When the player hits an object of an instance of InteractiveMapTileObject, the onPlayerBeginContact() method gets called, which looks like this:

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

Here, I am getting the objects of the "weapon" layer in the map, and then iterate through it to find the correct property and it's value. This works fine as it is.

The problem now is, that I obviously have multiple objects in the layer, and therefore multiple MapObjects. I need a way to identify the object, that the player collided with and then get it's property.

Is it possible to do that with the ContactListener, or do I need to implement something else? I already searched through a ton of posts, but didn't get lucky.

Johannes Mols
  • 890
  • 1
  • 12
  • 35

2 Answers2

1

I think instead of getting the weapon name from a MapObject get it from a Weapon class instead.

Every weapon can inherit from the InteractiveTileMapObject. When the player collides with the fixture you can get the reference from the user data and using the reference get the weapon name.

I hope this answer helped you and if you have any further questions please feel free to post a comment below!

Micheal O'Dwyer
  • 1,237
  • 1
  • 16
  • 26
  • I tried evaluating the user data, when colliding with the object,but I can't identify the collided object properties, I can only access the maps properties and all that like before. Here is a screenshot of the user data: https://imgur.com/a/GxJ2R – Johannes Mols Nov 12 '17 at 20:24
1

I solved my problem by writing a custom method in my abstract class to check for an intersection of each object in a specific object layer.

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

This is probably not the best solution, but it works wonderfully.

Johannes Mols
  • 890
  • 1
  • 12
  • 35