Box2D同步新身体在第一个世界步骤后变得清醒,即使我启动他们!醒来

时间:2012-04-22 13:57:59

标签: c++ box2d

嗨,我和Box2D玩得很开心。我正在研究一种需要与所有机构完全同步的网络游戏。 (不会有很多尸体)。

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

如果所有的身体都醒着,这个效果很好。然而,当我其中一个人睡着了时,模拟就变得没有了。睡眠体的位置,角度和速度只有几位小数。 实际上看起来他们只需要休息以搞砸同步。

所以我注意到的是,即使我明确地设置一个新的身体睡着了,在下一个世界步骤之后它将再次醒来。我猜这是因为Box2D需要检查某种新的物体。

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

如果我的校验和检查检测到offsync,则

目前正在每隔120帧重新同步所有实体。并继续这样做,直到他们再次同步。这会导致一些游戏对象的捕捉,但仍然可以很好地工作,但是对于游戏来说,首先不会出现异步同步。

服务器将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);

1 个答案:

答案 0 :(得分:0)

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

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