— Begin quote from ____
引用第12楼blazeandice于2015-01-20 11:56发表的 回 11楼(ctxdecoco) 的帖子 :
恩,感觉像帧率不稳定,造成的,我降低帧率 这种情况会减轻 http://www.cocoachina.com/bbs/job.php?action=topost&tid=206886&pid=1225328
— End quote
的确如此。
产生奇怪弹跳的原因应该是chipmunk计算不稳定造成的,而这个计算不稳定的因素来源于不稳定的帧率。
参见碰到同样问题的一个帖子:http://chipmunk-physics.net/forum/viewtopic.php?t=3250
chipmunk的作者slembcke建议采用稳定的timeStep(cpSpaceStep的传入参数)而不是变化的timeStep,因为chipmunk内部是保留了上一帧的物理计算结果并以此作为当前帧计算的初始迭代值。这样可以减少cpu开销。如果timeStep不一致的话将会导致当前帧的计算不稳定,通过增加迭代次数可以得到稳定的计算值,但是这样显然会增加cpu开销。参见:https://chipmunk-physics.net/forum/viewtopic.php?t=1939
注意到cocos2d-x 3.x不是采用的固定timeStep(比如如下是3.1版本的代码,来自void PhysicsWorld::update(float delta))
_updateTime += delta;
if (++_updateRateCount >= _updateRate)
{
_info->step(_updateTime * _speed);
for (auto& body : _bodies)
{
body->update(_updateTime * _speed);
}
_updateRateCount = 0;
_updateTime = 0.0f;
}
上面代码中_info->step就是调用了cpSpaceStep。但这里_updateTime显然是每帧不一样的,在帧率不稳定的情况下就容易得到不稳定的物理计算结果。
我测试了一下将直接调用_info->step(_updateTime*_speed)简单地替换成如下代码:
const double fixedDelterTime = 0.016;
double totTime = _updateTime * _speed;
while (totTime >= fixedDelterTime)
{
_info->step(fixedDelterTime);
totTime -= fixedDelterTime;
}
奇怪的弹跳问题就再也没出现过了。
如果考虑到每一帧都有一丁点剩余的时间没有传入cpSpaceStep处理的话,可以把当前帧剩余的时间保留到下一帧跟下一帧的delta加到一起处理。
我想cocos2d-x引擎组的人是否应该考虑一下将调用cpSpaceStep的地方改成固定timeStep调用。