过滤花栗鼠中被困尸体的碰撞



Background

  • 我正在为孩子们制作一个iOS应用程序,你可以用手指在屏幕上拖动球。
  • 我正在使用花栗鼠 7.0.0 进行物理模拟。
  • 我已经调整了花栗鼠演示代码来实现拖动功能。
  • 我使用的是 2 毫秒的固定时间步长。(我的应用程序没有更好的事情要做...

问题

我最近添加了代码,以便在球相互碰撞或与墙壁碰撞时播放声音,我在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时也是如此,听起来很糟糕。看起来球从墙上弹起,被约束推回墙上,冲洗,然后重复。在这种情况下,我只想播放一两次碰撞声音。

我尝试过的东西似乎不起作用...

  • 使用cpArbiterTotalKEcpArbiterTotalImpulse或相对速度进行过滤:脉冲、动能和相对速度都在典型碰撞的范围内。
  • 使用separate回调:球确实多次从墙上反弹。
  • 减小步长:物理引擎实际上需要更长的时间来收敛。
  • 速率限制音效:更好,但即使球看起来是静止的,它仍然会发出噪音。

问题

有没有办法过滤被困尸体的碰撞?

一个简单有效的解决方案是避免快速连续播放声音。

当球与墙壁接触时,检查球的"上次接触"计时器是否低于当前时间。如果是这样,请播放声音并将球的"最后一次接触"时间设置为当前时间加上 x,其中 x 是声音不应再次播放的超时持续时间(即 0.5 秒)。

在 cocos2d-iPhone 中,您可以添加更新方法的 deltaTime 来跟踪时间。还有许多方法可以获取系统时间,例如[NSDate date].timeIntervalSince1970为您提供自 1970 年以来的当前秒数。我知道,这似乎很荒谬,但是如果你稍后再得到这个数字,并减去之前的秒数,你得到的差值以秒为单位,这就是最重要的。

所以你正在使用约束来拖动球,并且球是弹性的,对吗?您是否尝试过调整约束参数?如果约束具有较低的最大力,则振荡的机会将显着下降。

另一件有帮助的事情是增加空间的碰撞倾斜(允许重叠的形状数量)。默认值为 0.1(无论您使用什么比例),但将其增加到一个像素左右可以显着帮助此类事情,而不会非常明显。

最新更新