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