育儿Box2D机构

时间:2013-12-10 10:16:08

标签: c++ box2d

我有一些问题在一起养育身体。当我将多个夹具连接到一个主体时,它似乎在内存管理中产生问题。这在碰撞期间发生,因此使用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;

}

非常感谢任何帮助!

1 个答案:

答案 0 :(得分:1)

我没有在Box2d中看到除了身体/夹具关系之外的任何父母关系。

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

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

如果您的目标是让一个GameObject管理多个实体(即一群东西),那么让单个GameObject维护一个包含多个实体的列表并对其进行管理。

然而,我相信你希望他们都像移动一样移动。据我所知,只有两种方法可以使两个物体表现为“一”。

选项#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);
}

您也可以使用焊接接头。

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

来自手册:

  

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

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

选项#2: 将其作为固定装置直接安装在车身上。我认为你必须创造破坏旧体并为此创造一套新的固定装置。

这有用吗?