当前位置: 首页 > 知识库问答 >
问题:

Libgdx平铺贴图对象到box2d主体位置

张宣
2023-03-14

平铺贴图对象以像素表示x、y位置,以度表示旋转。

我正在从地图上加载坐标和旋转,并试图将它们指定给box2d实体。位置模型之间存在一些差异,例如平铺对象旋转以度为单位,而box2d躯干角度以弧度为单位。

如何将位置转换为BodyDef坐标x、y和角度,以便在正确的位置创建实体?

使用代码:

 float angle = -rotation * MathUtils.degreesToRadians;
 bodyDef.angle = angle;
 bodyDef.position.set(x, y);

当旋转为0时工作,但当旋转不同于0时,主体定位不正确。

我在这里找到了一些提示:

http://www.tutorialsface.com/2015/12/qu ... 解dx/

这里:

https://github.com/libgdx/libgdx/issues/2742

这似乎解决了这个确切的问题,但这两种解决方案都不适用于我,在应用这些变换后,身体对象仍然定位错误。通过定位错误,我的意思是身体被定位在地图上它应该在的区域,但根据它的旋转稍微偏离。

我觉得应该很简单,但我不知道如何协调平铺和box2d位置之间的差异。

以下是我在上面的链接中尝试的两种解决方案(将x、y、宽度和高度的值从像素转换为世界单位后),以供参考:

float angle = rotation * MathUtils.degreesToRadians;
bodyDef.angle = -angle;
Vector2 correctionPosition = new Vector2(
        height * MathUtils.cosDeg(-rotation - 90),
        height + height * MathUtils.sinDeg(-rotation - 90));
bodyDef.position.set(x, y).add(correctionPosition);

    float angle = rotation * MathUtils.degreesToRadians;

    bodyDef.angle = -angle;

    // Top left corner of object
    Vector2 correctedPosition = new Vector2(x, y + height);

    // half of diagonal for rectangular object
    float radius = (float)Math.sqrt(width * width + height * height) / 2.0f;

    // Angle at diagonal of rectangular object
    float theta = (float)Math.tanh(height / width) * MathUtils.degreesToRadians;

    // Finding new position if rotation was with respect to top-left corner of object.
    // X=x+radius*cos(theta-angle)+(h/2)cos(90+angle)
    // Y=y+radius*sin(theta-angle)-(h/2)sin(90+angle)
    correctedPosition = correctedPosition
            .add(
                    radius * MathUtils.cos(theta - angle),
                    radius * MathUtils.sin(theta - angle))
            .add(
                    ((height / 2) * MathUtils.cos(MathUtils.PI2 + angle)),
                    (-(height / 2) * MathUtils.sin(MathUtils.PI2 + angle)));

    bodyDef.position.set(correctedPosition);

任何暗示都将受到高度欢迎。

共有1个答案

阎志义
2023-03-14

找到了正确的解决方案,失去了大约一天的生命:)

以上链接中的信息不正确和/或过时。当前平铺根据对象的类型保存对象位置。因为图像是相对于左下角的位置。

Box2d没有真正的原点,但是您可以考虑它的中心和连接到主体的固定装置的形状应该相对于(0,0)定位。

步骤1:读取平铺属性

        float rotation = textureMapObject.getRotation();

        float x = textureMapObject.getX();
        float y = textureMapObject.getY();

        float width = textureMapObject.getProperties()
            .get("width", Float.class).floatValue();
        float height = textureMapObject.getProperties()
            .get("height", Float.class).floatValue();

第二步:根据您的box 2d世界大小缩放这些值,例如x=x*1/25;等等。

第三步:创建一个没有任何位置或角度的身体。

第4步:使用以下工具变换身体位置和角度:

    private void applyTiledLocationToBody(Body body, 
        float x, float y, 
        float width, float height, 
        float rotation) {
    // set body position taking into consideration the center position
    body.setTransform(x + width / 2, y + height / 2, 0);

    // bottom left position in local coordinates
    Vector2 localPosition = new Vector2(-width / 2, -height / 2);

    // save world position before rotation
    Vector2 positionBefore = body.getWorldPoint(localPosition).cpy();

    // calculate angle in radians
    float angle = -rotation * MathUtils.degreesToRadians;

    // set new angle
    body.setTransform(body.getPosition(), angle);

    // save world position after rotation
    Vector2 positionAfter = body.getWorldPoint(localPosition).cpy();

    // adjust position with the difference (before - after) 
    // so that the bottom left position remains unchanged
    Vector2 newPosition = body.getPosition()
            .add(positionBefore)
            .sub(positionAfter);
    body.setTransform(newPosition, angle);
}

希望有帮助。

 类似资料:
  • 我想让我的libgdx地图滚动,但我不知道代码使地图滚动,请大家帮助我,我想让地图滚动像flappy bird游戏,这是我的代码,显示在屏幕上的地图 }

  • 我正在制作一个塔防游戏,因为我希望制作很多投射物,所以我想我会把它们放在一起。然而,我的投射物有用于碰撞检测的身体场和固定装置,当我对投射物调用free()时,它们的身体仍然存在。 所以我试图用世界毁灭尸体。destroyBody(),但这会导致空指针错误,除非我在外部显式执行。通过像我在这里学到的那样标记我的对象。但是,当我尝试实现这种方法来摧毁尸体时,出现了一些错误,因为被摧毁的尸体与释放弹丸

  • 我正在编程一个小游戏,它是基于瓷砖的。但当我渲染它的时候,有时那些瓷砖之间的一个小空间是可见的,(绿色)背景是暴露的(可以在视频中看到)。 我想知道,是否有一些双缓冲技术,可以解决这个bug,但我读到,双缓冲已经实现了。

  • 我能得到一个如何让图像出现在box 2d主体上的简单答案吗?我试着为图像和主体制作一个x和y int,但是一旦主体移动,图像就会保持静态。如果你回答了,请尽可能解释代码。如果你对我的完整源代码感兴趣,请查看我的帖子:http://www.java-gaming.org/topics/libgdx-drawing-a-sprite-on-to-a-box2d-body/33894/msg/31992

  • 我用这个简单的if来改变 “currentMap”是当前正在渲染的平铺贴图。“currentRoom”是指当前房间中有瓷砖贴图的房间,因为我需要更多的东西来存储房间。问题是,当我走到门口时,游戏立即以空指针关闭,然而在崩溃之前,我可以看到地图发生了变化。 完整错误报告: 一些额外的代码,这些代码在init上调用。房间-字符串的哈希图,其中包含表示门的方向的字母(键),以及表示值的平铺贴图(由于门的

  • 我正在使用LibGdx中的Box2D创建一个平台游戏。我有一个算法可以将瓷砖转换成固定装置。我用Contact Listener来判断球员是否在空中,但问题是,因为我使用的是相邻的固定装置, |瓷砖| |瓷砖| |瓷砖| 联系人侦听器在调用contact begin后调用contact end,当我通过相邻的互动程序并将MOB_AIR值设置为true时,即使我在地面上也无法跳跃。 代码的其他部分(