我有一些问题在一起养育身体。当我将多个夹具连接到一个主体时,它似乎在内存管理中产生问题。这在碰撞期间发生,因此使用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;
}
非常感谢任何帮助!
答案 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: 将其作为固定装置直接安装在车身上。我认为你必须创造破坏旧体并为此创造一套新的固定装置。
这有用吗?