Я пытался внедрить FRIM-систему для своей игры последние пару дней. Я провел некоторое исследование и натолкнулся на this article - он казался достаточно простым для реализации, поэтому я получил начал. Все, кажется, работает нормально, за исключением того, что я получаю временное сглаживание (движущиеся тела, похоже, немного продвигаются вперед) - это происходит, когда обрабатываются все шаги Box2D .... Я думаю.Box2D - FRIM (независимое от частоты кадров движение)
private const FIXED_TIMESTEP:Number = 1/60;
private const velocityIterations:int = 8;
private const positionIterations:int = 3;
private var fixedTimestepAccumulator:Number = 0;
private var fixedTimestepAccumulatorRatio:Number = 0;
public function Step(dt:Number):void
{
//dt - time between frames - I'm passing the e.passedTime - from the enter frame event; using Starling
fixedTimestepAccumulator += dt;
var nSteps:uint = Math.floor(fixedTimestepAccumulator/FIXED_TIMESTEP);
if (nSteps > 0)
{
fixedTimestepAccumulator = fixedTimestepAccumulator - nSteps * FIXED_TIMESTEP;
}
fixedTimestepAccumulatorRatio = fixedTimestepAccumulator/FIXED_TIMESTEP;
var nStepsClamped:int = Math.min(nSteps, MAX_STEPS);
for (var i:int = 0; i < nStepsClamped; ++i)
{
resetSmoothStates();
singleStep(FIXED_TIMESTEP);
}
world.ClearForces();
smoothStates();
}
private function resetSmoothStates():void
{
for (var bb:b2Body = world.GetBodyList(); bb; bb = bb.GetNext())
{
if (bb.GetUserData() is MyUserData && bb.GetType() != b2Body.b2_staticBody )
{
//each of my bodies have a reference to their sprite (actor) in userData
var _userdata:MyUserData=bb.GetUserData();
_userdata.x = _userdata.bodyPreviousX = bb.GetPosition().x * RATIO;
_userdata.y= _userdata.bodyPreviousY = - bb.GetPosition().y* RATIO;
_userdata.rotation = _userdata.bodypreviousRotation= _userdata.bodypreviousRotation = - bb.GetAngle();
}
}
}
private function smoothStates():void
{
var oneMinusRatio:Number = 1.0 - fixedTimestepAccumulatorRatio;
for (var bb:b2Body = world.GetBodyList(); bb; bb = bb.GetNext())
{
if (bb.GetUserData() is MyUserData && bb.GetType() != b2Body.b2_staticBody )
{
var userdata=bb.GetUserData();
userdata.x = (fixedTimestepAccumulatorRatio * bb.GetPosition().x * RATIO + oneMinusRatio * userdata.bodyPreviousX) ;
userdata.y = (- fixedTimestepAccumulatorRatio * bb.GetPosition().y * RATIO + oneMinusRatio * userdata.bodyPreviousY) ;
userdata.rotation = (- fixedTimestepAccumulatorRatio * bb.GetAngle() + oneMinusRatio * userdata.bodypreviousRotation);
}
}
}
private function singleStep(dt:Number):void
{
Input();
world.Step(dt, velocityIterations, positionIterations);
}
Что я делаю неправильно?
Любая помощь, предложения будут высоко оценены. Thanks
Я только шаг (обновляю) физику с помощью фиксированного шага времени (FIXED_TIMESTEP) .... так что nSteps - это количество шагов, которые я могу вместить за время, которое накопилось .... nStepsClamped - это просто предел, не выходят из строя, когда частота кадров падает (выполняется только максимум 5 шагов физики). – Iansen
Моя проблема, скорее всего, с интерполяцией позиций спрайтов ... но я не могу понять, что случилось. – Iansen
Хммм ... как правило, в Box2D, позиции спрайтов задаются с чем-то вроде: Vec2 bodyPos = body.GetPosition(); Vec2 spritePos (bodyPos.x * PTMRatio, bodyPos.y * PTMRatio). PTMRatio обычно 32 или переменная (см. Http://nonlinearideas.com/viewports/), но не 1: 1 в руководстве. Странно, что это вызовет скачок, если он не будет обертывать ... – FuzzyBunnySlippers