Libgdx与TiledMap的碰撞检测

8

我正在尝试通过瓦片地图实现碰撞检测系统的功能。我有一个二维“口袋妖怪风格”的游戏,其中呈现了一个瓦片地图。具体来说,我在我的 tiled map .tmx 文件中有一个'collision'层,我想让玩家和其他实体与之交互。我的问题是如何将玩家精灵 (扩展了 Sprite 类) 连接到瓦片地图的 'collision' 层,并在两者之间引起碰撞。感激任何建议。

1个回答

15
首先,你的Player 可能不应该extend Sprite,因为你的玩家通常比一个Sprite更复杂。它可能由多个精灵或甚至Animations组成。将一个精灵作为玩家的属性保留。
这个问题已经被多次解决了。一般需要以下步骤:
  1. 找到地图中的碰撞层
  2. 从该层提取所有对象
  3. 检查每个对象是否发生碰撞
在代码中,这可能看起来像这样:
int objectLayerId = 5;
TiledMapTileLayer collisionObjectLayer = (TiledMapTileLayer)map.getLayers().get(objectLayerId);
MapObjects objects = collisionObjectLayer.getObjects();

// there are several other types, Rectangle is probably the most common one
for (RectangleMapObject rectangleObject : objects.getByType(RectangleMapObject.class)) {

    Rectangle rectangle = rectangleObject.getRectangle();
    if (Intersector.overlaps(rectangle, player.getRectangle()) {
        // collision happened
    }
}

这里有更多你可能感兴趣的链接:


我实现了你的代码,但是对象返回了0计数,并且循环从未运行。你有什么想法吗?我的图层中没有任何对象,只有一个充当背景且不需要碰撞的图层和一个充当玩家可以碰撞的瓷砖的图层。 - bhafenri
当你写道“我有一个‘碰撞’层”时,我假设你在TilEd中使用了一个对象层。你应该这样做,因为这样建模碰撞非常方便,而且在代码中使用也很容易。如果按照你的方法,你将不得不遍历所有碰撞层中的瓷砖,并为它们创建一个矩形。我仍然建议你使用对象层。 - noone
好的,谢谢你的帮助!我终于想通了。 - bhafenri
@noone,如果我们每帧都检查每个矩形的“重叠”,会不会占用太多资源?我见过一种方法,使用一个由1或0组成的数组来检测瓷砖是否可行走。你有没有在许多对象上使用“重叠”方法时遇到过问题(例如在移动设备上)? - Paul
1
@Paul 我认为简单的边界框碰撞检测不需要担心,即使在移动设备上和有许多矩形的情况下也是如此。你可以进行优化,但只要没有遇到问题并且已经分析了问题的来源,就不应该进行预先优化。 - noone
1
没有什么可以阻止你在加载时提取所有形状,然后构建四叉树或类似的数据结构来加速碰撞检测,如果你预计会有很多复杂性。 - Shayne

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接