【问题标题】:Libgdx: Tiled Objects layer for collisionLibgdx:用于碰撞的平铺对象层
【发布时间】:2013-07-26 08:18:47
【问题描述】:

先生们,您好,

我现在想弄清楚如何使用平铺对象图层为我的玩家执行碰撞检测,更具体地说,我希望它检测我在平铺地图中绘制的折线。当我在谷歌中研究 Tiled 的碰撞检测时,我发现了这个简单的例子superkoala sample for TiledmapLayer。根据我对代码的理解(如果我错了,请纠正我),为了检测碰撞,玩家将读取某个层的每个图块,例如包含地面和其他对象的前景层。

基本上,我对我的对象层所做的就是将我的折线命名为 Wall,并且我输入的类型取决于我使用了多少折线。这样我就可以为我的碰撞调用这个墙号,以备将来使用。

谁能给我一个关于读取对象并将它们用于碰撞检测的示例代码?或者只是一个简单的提示或关于我如何解决这个问题的想法?任何帮助将不胜感激。

【问题讨论】:

    标签: java android collision-detection libgdx tile


    【解决方案1】:

    在您的情况下,我建议不要使用对象图层,而是使用特定图块的属性。假设您在“平铺”中有一个瓷砖,并且您确定只将其用作墙壁。单击该特定图块并添加“已阻止”属性。然后,在您的代码中,您可以检查玩家旁边的每个单元格,如果它包含“阻塞”属性,则不允许玩家朝那个方向前进。这是我如何做到的伪代码:

    private boolean isCellBlocked(float x, float y) {
        Cell cell = null;
        boolean blocked = false;
    
        try {
            cell = collisionLayer.getCell((int) (x / collisionLayer.getTileWidth()), (int) (y / collisionLayer.getTileHeight()));
        } catch (Exception e) {
            e.printStackTrace();
        }
    
        if (cell != null && cell.getTile() != null) {
            if (cell.getTile().getProperties().containsKey("blocked")) {
                blocked = true;
            }
        }
        return blocked;
    }
    

    你可以让玩家在每次更新时拨打isCellBlocked(x, y)

    我还为每一面都做了一个collidesSide(float x, float y)collidesTop(float x, float y) 等)。

    我希望这对您有所帮助,即使它不使用您想要的系统。如需更多帮助,我在一个大型项目中大量使用 libGDX 进行碰撞检测,因此请随时与我联系!

    【讨论】:

    • 我想知道您为什么建议不要使用对象层。相交的矩形要少得多。您的解决方案无疑是有效的,但更多的是说明您是如何做到的,而不是探索对象层的使用,从而大大简化了属性编辑。
    • @RichieHH 我总是发现在 TileD 中使用属性而不是处理对象层更容易。
    • 为什么?如果您使用磁贴,则需要为每个磁贴添加和解析属性。当您可以在对象层上拥有具有完全相同属性的单个对象并在许多情况下生成单个 B2D 主体时,为什么要这样做? gist.github.com/anonymous/a2c61d04572455c75fcd
    • 好的,这是一个 1 岁的帖子。如果您愿意,只需发布​​一个新答案即可。
    • 帖子的年龄不相关,但公平地说,我的答案在使用 box2d 时更合适,这在上面还不清楚:解析对象层并创建 box2d 主体 - 让 box2d 采用碰撞检测 -移动时无需轮询周围环境,并且一切都在 box2d 世界坐标中的额外好处。
    【解决方案2】:

    我遇到了这个问题/答案并想分享我使用的东西,我还没有完全弄清楚一切,但它一直对我有用:

        void buildMap() {
            MapLayer collisionLayer = (MapLayer) map.layers.find { it.name == 'collision' }
            collisionLayer.objects.each { MapObject mapObject ->
                Body body = null
    
                if(mapObject instanceof RectangleMapObject) {
                    Rectangle rectangle = adjustRectangleDimensions(mapObject.rectangle)
                    body = bodyFactory.makeBoxPolyBody(
                            rectangle.x,
                            rectangle.y,
                            rectangle.width,
                            rectangle.height,
                            BodyFactory.STONE,
                            BodyDef.BodyType.StaticBody
                    )
                }
    
                if(mapObject instanceof PolygonMapObject) {
                    Polygon polygon = adjustPolygonDimensions(mapObject.polygon)
                    body = bodyFactory.makePolygonShapeBody(
                            polygon.vertices,
                            polygon.x,
                            polygon.y,
                            BodyFactory.STONE,
                            BodyDef.BodyType.StaticBody
                    )
                }
    
    
                body.fixtureList.first().filterData.categoryBits = GROUND_BIT
                body.fixtureList.first().filterData.maskBits = PLAYER_BIT // can combine with | if multiple i.e. GROUND_BIT | PLAYER_BIT
            }
        }
    
        static Rectangle adjustRectangleDimensions(Rectangle rectangle) {
            rectangle.x = rectangle.x * RenderingSystem.PIXELS_TO_METRES * 2 as float
            rectangle.y = rectangle.y * RenderingSystem.PIXELS_TO_METRES * 2 as float
            rectangle.width = rectangle.width * RenderingSystem.PIXELS_TO_METRES * 2 as float
            rectangle.height = rectangle.height * RenderingSystem.PIXELS_TO_METRES * 2 as float
            return rectangle
        }
    
        static Polygon adjustPolygonDimensions(Polygon polygon) {
            float x = polygon.x * RenderingSystem.PIXELS_TO_METRES as float
            float y = polygon.y * RenderingSystem.PIXELS_TO_METRES as float
            polygon.setPosition(x, y)
    
            float[] vertices = polygon.vertices //might need to get transformedVertices at some point, seems to work now
            def adjustedVertices = []
            vertices.each {
                adjustedVertices.add(it * RenderingSystem.PIXELS_TO_METRES as float)
            }
    
            polygon.vertices = adjustedVertices
    
            return polygon
        }
    

    在这种情况下,RenderingSystem.PIXELS_TO_METRES 是我用于 OrthogonalTiledMapRenderer 的单位比例。

    我使用的bodyFactory可以找到https://github.com/lifeweaver/learningGames/blob/master/core/src/net/stardecimal/game/BodyFactory.groovy

    另请参阅https://github.com/yichen0831/Pacman_libGdx/blob/master/core/src/com/ychstudio/builders/WorldBuilder.java 以获取另一个示例。

    【讨论】:

      猜你喜欢
      • 2013-04-22
      • 2023-04-02
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-10-09
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多