背景
问题
我最近添加了代码来播放声音,只要球相互碰撞或与墙碰撞,我正在postSolve
回调中进行:
static void postSolve(cpArbiter *arb, cpSpace *space, cpDataPointer userData)
{
GameLayer *layer = (__bridge GameLayer *)userData;
[layer collisionHandler:arb];
}
-(void) collisionHandler:(cpArbiter*)arb
{
if(cpArbiterIsFirstContact(arb)) {
[[SimpleAudioEngine sharedEngine] playEffect:kCollisionEffectFilename];
}
}
问题在于......当我将球拖入墙壁时,即使在cpArbiterIsFirstContact
上进行过滤,也会产生大量的碰撞,这听起来很糟糕。似乎球从墙上反弹,被约束驱赶回墙壁,冲洗并重复。在这种情况下,我只想播放一次或两次碰撞声。
我尝试过的似乎不起作用的事情......
cpArbiterTotalKE
,cpArbiterTotalImpulse
或相对速度进行过滤:脉冲,动能和相对速度均在典型碰撞范围内。separate
回调:球真的多次从墙上反弹。问题
有没有办法过滤被困物体的碰撞?
答案 0 :(得分:1)
一个简单而有效的解决方案是避免快速连续播放声音。
当球与墙壁接触时,检查球的“最后接触”计时器是否低于当前时间。如果是这样,播放声音并将球的“最后接触”时间设置为当前时间加x,其中x是声音不应再次播放的超时持续时间(即0.5秒)。
在cocos2d-iphone中,您可以添加更新方法的deltaTime来跟踪时间。还有很多方法可以获得系统时间,例如[NSDate date].timeIntervalSince1970
给出了自1970年以来的当前秒数。我知道,这看起来很荒谬,但是如果你以后再次获得这个数字,并减去之前的数字只需几秒钟即可获得差异,这就是重要的。
答案 1 :(得分:1)
所以你使用约束来拖动球,球是否有弹性?您是否尝试过调整约束参数?如果约束具有较低的maxForce,则振荡的可能性将显着下降。
另一件可以帮助的事情是增加空间的碰撞斜率(允许多少形状重叠)。默认值为0.1(无论您使用的是什么比例),但将其增加到像素左右可以显着帮助这种事情,而不会非常明显。