下面是我的时间步长:
void step(float dt){
static double UPDATE_INTERVAL = 1.0f/60.0f;
static double MAX_CYCLES_PER_FRAME = 5;
static double timeAccumulator = 0;
timeAccumulator += dt;
if (timeAccumulator > (MAX_CYCLES_PER_FRAME * UPDATE_INTERVAL))
{
timeAccumulator = UPDATE_INTERVAL;
}
int32 velocityIterations = 3;
int32 positionIterations = 2;
while (timeAccumulator >= UPDATE_INTERVAL)
{
timeAccumulator -= UPDATE_INTERVAL;
this->world->Step(UPDATE_INTERVAL,
velocityIterations, positionIterations);
this->world->ClearForces();
}
}虽然这个游戏无论帧速率如何都能很好地工作,但它会导致精灵“颤动”或“卡顿”,即使帧速率是60fps!
我认为这是因为精灵的每一帧都移动了不同的量,因为每一帧执行while循环的次数是不同的。
固定时间步长的更好方法是什么?我读了很多关于固定时间步长的文章,感到非常困惑。上面的“工作”除了卡顿。
编辑:只是为了澄清,颤动非常小!视力不佳的人不会注意到这一点,但如果你仔细观察,它会使游戏看起来非常低的预算。这让游戏看起来并不流畅。
发布于 2015-08-12 18:56:00
你没有正确夹住你的timeAccumulator:
timeAccumulator += dt;
if (timeAccumulator > (MAX_CYCLES_PER_FRAME * UPDATE_INTERVAL))
{
timeAccumulator = UPDATE_INTERVAL;
}应该是
timeAccumulator = std::min(dt + timeAccumulator, MAX_CYCLES_PER_FRAME * UPDATE_INTERVAL);关于单步执行:您需要根据timeAccumulator中的剩余部分,用下一个完整的步骤插入上一个完整的步骤。Allan Bishop有一个关于这方面的教程,尽管原始站点不再可访问(blog.allanbishop.com)。下面是他平滑步骤(只有最后一个具有小数步骤)的样子:
// for the remaining timeAccumulator < UPDATE_INTERVAL
fixedTimestepAccumulatorRatio = timeAccumulator / UPDATE_INTERVAL;
private function smoothStates():void
{
const oneMinusRatio:Number = 1.0 - fixedTimestepAccumulatorRatio;
//Makes it easier to wrap up the Box2D body in another object so we can track other variables.
for each (var body:Body in bodies)
{
var box2Dbody = body.box2DBody;
texture.position.x = fixedTimestepAccumulatorRatio * box2Dbody.GetPosition().x + oneMinusRatio * body.previousPosition.x;
texture.position.y = fixedTimestepAccumulatorRatio * box2Dbody.GetPosition().y + oneMinusRatio * body.previousPosition.y;
texture.rotation = box2Dbody.GetAngle() * fixedTimestepAccumulatorRatio + oneMinusRatio * body.previousAngle;
}
}https://stackoverflow.com/questions/31962978
复制相似问题