【问题标题】:Parenting Box2D bodies育儿 Box2D 身体
【发布时间】:2013-12-10 10:16:07
【问题描述】:

我在养育身体时遇到了一些问题。当我将多个固定装置附加到主体时,似乎会在内存管理中产生问题。这发生在碰撞期间,因此使用 XCode 我收到以下错误消息:

 *** error for object 0xf572ef0: incorrect checksum for freed object - object was probably    modified after being freed.
 *** set a breakpoint in malloc_error_break to debug

当物体只有一个固定装置时不会发生这种情况。

我想要达到的目标是,例如,如果一个角色拿起一个物品,那么转换就会成为父母的孩子。所以,我们会得到:

 Parent_R + Child_R
 Parent_P + Child_P

由于我在物理引擎的上下文中,我会假设有一种方法可以在对象之间创建父/子关系。我可以简单地从物理世界中分离对象(比如之前坠落的对象)并将其视为纯精灵游戏对象。这涉及到相当多的来回(例如在放回物理世界时重新创建夹具/主体)。这是我的代码:

void GameObject::AttatchToBody(GameObject& obj1, GameObject& obj2, b2World& world)
{
    b2PolygonShape boxShape;
    boxShape.SetAsBox(obj2.width, obj2.height);

    b2FixtureDef boxFixtureDef;
    boxFixtureDef.restitution = 0.2f;
    boxFixtureDef.friction = 0.3f;
    boxFixtureDef.shape = &boxShape;
    boxFixtureDef.density = 1 / (obj2.width + obj2.height);

    obj2.fixture = obj1.body->CreateFixture(&boxFixtureDef);
    obj2.body = obj1.body;

}

非常感谢任何帮助!

【问题讨论】:

    标签: c++ box2d


    【解决方案1】:

    我没有在 Box2d 中看到除了 body/fixture 关系之外的任何养育关系。

    在我看来,您的 obj1 和 obj2 引用了同一个 Box2d 内存分配对象(主体)。例如,当您删除 obj1 时,您可能会删除附加到它的主体(通过执行类似 world->DestroyBody(...) 的操作)。下一次 box2d 更新,您正在引用一个您没有分配并被告知要销毁的对象(对 Box2d 系统)。这可能是问题吗?

    我还看到您在 obj2 和 obj1 之间共享一个夹具。当 obj1 被 box2d 系统回收时会发生什么(即你破坏了 obj1 的主体)?这似乎不正确...系统不知道您的育儿关系,并且 C++ 没有内置的引用计数系统。这也可能是问题所在。

    如果您的目标是让单个 GameObject 管理多个 body(即一群东西),那么让单个 GameObject 维护多个 body 的列表并管理它们。

    但是,我相信您希望它们都像附着一样移动。据我所知,只有两种方法可以使两个物体表现为“一个”。

    选项 #1: 第一种是使用它们之间的联合。我在一个游戏中做到了这一点,我让一艘太空船撞到了一件武器来捡起它。当船这样做时,我创建了一个棱柱接头,这样枪就会看起来“安装”在船的前面。这是我用来附加它的代码:

    void BulletLauncherEntity::CreateJointConnection()
    {
       Entity* owner = GetOwner();
       Body& ownerBody = owner->GetBody();
    
       // We put the position of this at the tip of the
       // owner.
       float32 launcherDist = 0.5*(owner->GetScale())*Constants::SCALE_TO_METERS_RATIO();
       float32 launcherSize = 0.5*GetScale()*Constants::SCALE_TO_METERS_RATIO();
       // Joint along axis of entity
       b2PrismaticJointDef jointDef;
       // Note that the "Initialize" function in the
       // jointDef did not really give us what we wanted.
        jointDef.bodyA = &ownerBody;
        jointDef.bodyB = &GetBody();
        jointDef.localAnchorA = Vec2(launcherDist-launcherSize,0);
        jointDef.localAnchorB = Vec2::Zero();
        jointDef.localAxisA = Vec2(1,0);
        jointDef.referenceAngle = 0;
    
       jointDef.lowerTranslation = -launcherDist;
       jointDef.upperTranslation = 0.5*GetScale()*Constants::SCALE_TO_METERS_RATIO();
       jointDef.enableLimit = true;
       jointDef.maxMotorForce = 2.0;
       jointDef.motorSpeed = 0.25;
       jointDef.enableMotor = true;
       jointDef.collideConnected = false;
       ownerBody.GetWorld()->CreateJoint(&jointDef);
    }
    

    您也可以使用焊接接头。

    但是,根据手册,使用焊接接头不会产生“僵硬”的连接。它有一些柔软性,因为在碰撞过程中需要满足约束。

    来自手册:

    焊接接头试图约束两个之间的所有相对运动 身体。查看测试台中的 Cantilever.h 以了解焊接接头如何 行为。使用焊接接头来定义易碎是很诱人的 结构。但是,Box2D 求解器是迭代的,因此关节是 有点软。因此,通过焊接接头连接的主体链会弯曲。 相反,最好从单个开始创建可破坏的主体 具有多个固定装置的主体。当身体断裂时,你可以摧毁一个 夹具并在新的身体上重新创建它。请参阅中的 Breakable 示例 测试平台。

    我没有尝试对此进行测试,或者查看其他类型的关节有多“僵硬”。当我使用棱柱关节时,它对我来说似乎很坚固。但它确实在碰撞过程中偶尔会被“推入”。

    选项 #2: 将其作为固定装置直接连接到车身上。我认为您将不得不为此创建销毁旧身体并创建一组新固定装置。

    这有帮助吗?

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多