如何使用Chipmunk物理引擎检测永久碰撞?

3
我试图在球形物体撞击其他任何形状时播放“boing”声音。这个方法有效,但效果有点过头了...
当球停止运动或开始滚动时,它会与接触到的任何物体永久碰撞,因此“boing”声音不断触发。
我在chipmunk文档中找不到任何关于如何判断两个物体是否永久碰撞的信息。所以我想我必须自己想办法解决,可能需要使用某种计时器来比较上一次碰撞和当前碰撞。但这听起来很hacky。
有人解决过这个问题吗?你是怎么解决的?

不是椰子,但你应该检查撞击的速度来弄清楚这个问题吧? - user1228
我考虑过这个问题,但似乎无法访问chipmunk中形状的速度。但有99%的可能是因为我对C、Objective C和Cocoa都很陌生,所以做错了什么。 - gargantuan
3个回答

2
我认为我接下来要说的不是一个好的实践方法,但我相信它可以解决你的问题:
1. 对于每个对象,保留两个状态变量:(1)上次碰撞的物体,(2)上次碰撞时间。
2. 在碰撞时,仅当碰撞的物体不同(且为球)或自上次碰撞以来经过了一定的“时间差”时,才播放声音。然后记录最后的碰撞统计信息。
这非常简单且非常有效:
// In your ball interface
id lastCollisionObject;
double lastCollisionTime;


// When a collision occurs...
double now = GetTime();
id other = GetCollisionObject();
if ((now - lastCollisionTime) > 0.3 || other != lastCollisionObject) {
    PlaySound(kBoingSound);
}
lastCollisionObject = other;
lastCollisionTime = now;

实际上,我认为你的建议是非常好的实践,除了缺少一个警告来确保ID不能被重复使用 - 想象一下击中“最后创建的对象”,让它爆炸,然后再击中另一个对象,却没有意识到它是因为分配了相同的“最高ID”。 - Andy Dent

2

当接触被中断时,您是否可以播放“boing”声音?在chipmunk中有一个回调函数:typedef void (*cpCollisionSeparateFunc)(cpArbiter *arb, struct cpSpace *space, void *data)

这样,每次弹跳时都会得到“boing”的声音,但是在滚动时不会播放。当然,当它从您的形状上滚落时,您也会得到一个声音,但这可能是一个功能,具体取决于您的看法。


1
如果一个球从斜坡上滚落,而不是在斜坡上弹跳,那么它在滚动时应该是静音的,但在弹跳时应该是响亮的。这两种情况都是在碰撞后分离的,因此我认为除非领域是只有弹跳而没有滚动或滑动的情况,否则将此操作放在“ on-separate ”中不是一个好选择。 - JJ Rohrer

1

在chipmunk中,形状没有速度,它们所附着的刚体才有速度。您可以通过以下方式访问速度:"myShape.body->v"。我认为您只需要检查速度是否超过某个阈值就可以知道何时发生了“碰撞”。您还可以检查旋转速度以查看球是否在滚动。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接