如何防止 Spritekit physicsbodies 在碰撞过程中相交?

How to prevent Spritekit physicsbodies from intersecting during collision?

所以我有一个与地面碰撞的动态矩形物理体(玩家),它不是动态的,也是一个矩形。

每当两者发生碰撞时,玩家的物理体都会略微穿过地面,然后弹回。我可以通过使用 println() 在每一帧记录角色的 Y 位置来直观地看到这一点:

117.405
107.206
96.3573
84.8607
72.7158
59.9225
46.4809
50.826   <-- Player's position dips down below surface of ground
52.3426
52.3685
52.3703
52.3704

两个物理体的恢复都设置为 0.0。我什至在一个空白项目中对此进行了测试,无论如何它似乎都会发生。

除了 Spritekit 奇异的物理学之外,是否有更好的方法来检测这种碰撞,使用光线投射、矩形相交或其他一些自定义实现?

不要放弃 SpriteKit 的物理引擎!首先,在你的物理体上设置这个属性:

yourPhysicsBody.usesPreciseCollisionDetection = YES;

请记住,当您尝试执行精确的高速碰撞时,这是有利的。 SpriteKit 物理通常受到 Sprite Kit 帧周期的限制,它调用更新然后执行动作,然后是物理,然后是绘图,等等,一遍又一遍。因此,如果您的碰撞非常快,可能根本没有足够的时间让它在某些帧内注册。另一方面,通过精确碰撞,您可以使用 SpriteKit 算法测试多个移动位置来精确定位接触。

如果失败了,你总是可以在碰撞发生之前在接触点附加一个薄的物理体(如果你知道节点会高速碰撞)。这将作为缓冲区在它们之间创建 space。

您是否尝试过调整 SKPhysicsBody 的速度?例如,您可以将 y 速度调整为永远不会超过更新循环中的最大值。或者,在发生接触时降低速度(甚至可能为 0)。

对于后一个建议,您应该使用位于主要 body 下方的附加物理 body 作为传感器。传感器是 SKNodeSKSpriteNode(在下图中),具有不受重力影响并固定到 parent 节点的动态 SKPhysicsBody。 body 不应与任何东西发生碰撞,而只是通过其 contactTestBitMask 响应与其他物理体的接触。它看起来像这样。

这可能不是 "Mario way" 的做法,但它可能会让您更接近某种感觉。

不确定这本身是否构成答案,但我决定为平台游戏实现我自己的物理学。

对于可能面临与我类似问题的任何人,我建议您也这样做。在我的另一个游戏 Piston Flip 中,我使用了 Spritekit 物理,因为该游戏包含物理体的一些变化,我从来不需要完全 重新创建相同的物理交互两次.因此,如果您制作的东西需要稍微复杂一点的物理学并且不需要精确复制,请使用 spritekit 物理学。

现在,如果您需要像平台游戏这样的精确度,我建议您自己实现。我使用 this tutorial 作为起点并从那里进行定制。抛开令人恼火的初始实施不谈,我现在真的很高兴我能如此准确地控制一切。