【问题标题】:Box2D sync new bodies become awake after first world step even if i init them to !awakeBox2D 同步新物体在第一个世界步骤后变得清醒,即使我将它们初始化为 !awake
【发布时间】:2012-04-22 13:57:59
【问题描述】:

您好,我正在玩 Box2D。我正在开发一款需要与所有身体完全同步的网络游戏。 (不会有很多尸体)。

所以计划是我启动一个服务器,里面有一些机构。服务器执行世界模拟步骤。然后过了一会儿客户端连接。当它这样做时,服务器将世界上所有主体的所有状态数据发送给客户端,客户端将它们创建为新主体。然后客户端将在客户端拥有完全同步的游戏副本。服务器上的任何小的更改都会被复制并作为消息发送到客户端。而且因为 Box2D 是确定性的,服务器端的任何更改都会在客户端表现得完全相同。

如果所有身体都醒着,这将非常有效。但是,当我其中一个人睡着时,模拟变得不同步。睡眠物体的位置、角度和速度只有几位小数。 实际上,他们似乎只需要休息一下就可以搞砸同步。

所以我注意到的是,即使我明确设置一个新的身体进入睡眠状态,在下一个世界步骤之后它会再次醒来。我猜这是因为 Box2D 需要对某种新实体进行检查。

有没有办法解决这个问题?并保持同步?

如果我的校验和检查检测到不同步,目前我每 120 帧重新同步一次所有主体。并继续这样做,直到它们再次不同步。这会导致一些游戏对象的捕捉,但仍然运行得非常好,但 id 宁愿游戏不会首先失去同步。

服务器会将 float 和 int 值发送给将使用以下代码创建主体的客户端。在服务器端创建主体时,服务器使用几乎相同的代码:

//------------create world---------------
b2Vec2 gravity(0.0f, -10.0f);
b2World world(gravity);
world.SetAllowSleeping(true);

//---------------create bodies from values sent by server----------------------
//body def
b2BodyDef bodyDef;

if(bodyType == static_body)
bodyDef.type = b2_staticBody;
else if(bodyType == dynamic_body)
bodyDef.type = b2_dynamicBody;
else
throw "error invalid body def types";

bodyDef.angle = angle;
bodyDef.angularDamping = angularDamping;
bodyDef.angularVelocity = angularVelocity;
bodyDef.gravityScale = gravityScale;

bodyDef.linearDamping = linearDamping;
bodyDef.linearVelocity.x = linearVelocityX;
bodyDef.linearVelocity.y = linearVelocityY;
bodyDef.position.x = positionX;
bodyDef.position.y = positionY;

bodyDef.active = isActive;
bodyDef.awake = isAwake;
bodyDef.bullet = isBullet;
bodyDef.fixedRotation = isFixedRotation;
bodyDef.allowSleep = isSleepingAllowed;

//body
// Call the body factory which allocates memory for the ground body
// from a pool and creates the ground box shape (also from a pool).
// The body is also added to the world.
body = world.CreateBody(&bodyDef);

//fixture def
b2PolygonShape polygonShape;
polygonShape.SetAsBox(shapeWidth, shapeHeight);

b2FixtureDef fixtureDef;
fixtureDef.shape = &polygonShape;
fixtureDef.restitution = 0.5f;  // air resistance / fluid resistance
fixtureDef.density = 1.0f;
fixtureDef.friction = 1.0f;

//fixture
body->CreateFixture(&fixtureDef);

//set mass inertia and center
b2MassData md;
md.center = b2Vec2_zero;
md.I = intertia;
md.mass = mass;
body->SetMassData(&md);

//these cannot be predefined for some reason, seems like a bug in box2d
body->SetFixedRotation(isFixedRotation);

//----------run game simulations-----------
float32 timeStep = 1.0f / 60.0f;
int32 velocityIterations = 6;
int32 positionIterations = 2;

world.Step(timeStep, velocityIterations, positionIterations);

【问题讨论】:

  • 能贴出body创建的代码吗?
  • 当然,但我不认为有什么问题。

标签: c++ box2d


【解决方案1】:

我在 box2d 论坛上问过,如果模拟在不同的时间步长开始,box2d 的内部状态似乎可能会有所不同。所以唯一的解决办法就是解决它。

http://www.box2d.org/forum/viewtopic.php?f=3&t=8462&p=36115#p36115

【讨论】:

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