LibGDX 碰撞时平铺获取对象 属性
LibGDX Tiled get object property on collision
我正在 LibGDX 开发一款游戏,并使用 Tiled 设置了一张地图。我向特定层中的对象添加了一个自定义字符串 属性 以获取更多信息,它代表什么对象。
我设置了一个 ContactListener,它调用地图对象的抽象 class 中的一个方法。侦听器看起来像这样:
@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);
}
}
}
在这里,我正在获取地图中 "weapon" 图层的对象,然后遍历它以找到正确的 属性 及其值。这很好用。
现在的问题是,我在图层中显然有多个对象,因此有多个 MapObject。我需要一种方法来识别玩家碰撞的物体,然后得到它 属性.
是否可以使用 ContactListener 来做到这一点,或者我是否需要实现其他东西?我已经搜索了很多帖子,但运气不好。
我认为与其从 MapObject 中获取武器名称,不如从 Weapon
class 中获取武器名称。
每种武器都可以继承自InteractiveTileMapObject
。当玩家与固定装置发生碰撞时,您可以从用户数据中获取引用并使用引用获取武器名称。
希望这个回答对您有所帮助,如果您有任何其他问题,请随时post在下方发表评论!
我通过在抽象 class 中编写自定义方法来检查特定对象层中每个对象的交集来解决我的问题。
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;
}
这可能不是最好的解决方案,但效果非常好。
我正在 LibGDX 开发一款游戏,并使用 Tiled 设置了一张地图。我向特定层中的对象添加了一个自定义字符串 属性 以获取更多信息,它代表什么对象。
我设置了一个 ContactListener,它调用地图对象的抽象 class 中的一个方法。侦听器看起来像这样:
@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);
}
}
}
在这里,我正在获取地图中 "weapon" 图层的对象,然后遍历它以找到正确的 属性 及其值。这很好用。
现在的问题是,我在图层中显然有多个对象,因此有多个 MapObject。我需要一种方法来识别玩家碰撞的物体,然后得到它 属性.
是否可以使用 ContactListener 来做到这一点,或者我是否需要实现其他东西?我已经搜索了很多帖子,但运气不好。
我认为与其从 MapObject 中获取武器名称,不如从 Weapon
class 中获取武器名称。
每种武器都可以继承自InteractiveTileMapObject
。当玩家与固定装置发生碰撞时,您可以从用户数据中获取引用并使用引用获取武器名称。
希望这个回答对您有所帮助,如果您有任何其他问题,请随时post在下方发表评论!
我通过在抽象 class 中编写自定义方法来检查特定对象层中每个对象的交集来解决我的问题。
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;
}
这可能不是最好的解决方案,但效果非常好。