嗨,我和Box2D玩得很开心。我正在开发一个网络游戏,它需要和所有的身体完全同步。(不会有很多身体)。
所以我的计划是启动一台服务器,里面有一些物体。服务器执行世界模拟步骤。然后过一段时间,客户端就会连接。当它这样做时,服务器将世界上所有实体的所有状态数据发送给客户端,客户端将创建它们作为新的主体。然后客户端就会有一个完全同步的游戏副本。服务器上的任何小更改都会复制并作为消息发送给客户端。而且由于Box2D是确定性的,所以服务器端的任何更改在客户机上的行为都是完全相同的。
如果所有的身体都醒着的话,这是很好的。然而,当他们中的一个睡着时,模拟就变得不同步了。睡眠体的位置、角度和速度只有几个小数点不同。,实际上,看起来他们只是需要休息一下才能搞砸同步.
所以我注意到,即使我明确地让一个新的身体进入睡眠状态,在下一个世界的一步之后,它将再次苏醒。我猜这是因为Box2D需要对一些新的身体进行检查。
有办法解决这个问题吗?保持同步?
目前,如果通过我的校验和检查检测到非同步,则每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);发布于 2012-05-16 15:05:10
我在box2d论坛上问过,如果模拟是从不同的时间步骤开始的话,box2d的内部状态可能会有所不同。所以唯一的解决办法就是绕开它。
http://www.box2d.org/forum/viewtopic.php?f=3&t=8462&p=36115#p36115
https://stackoverflow.com/questions/10268534
复制相似问题