如何防止 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 作为传感器。传感器是 SKNode
或 SKSpriteNode
(在下图中),具有不受重力影响并固定到 parent 节点的动态 SKPhysicsBody
。 body 不应与任何东西发生碰撞,而只是通过其 contactTestBitMask
响应与其他物理体的接触。它看起来像这样。
这可能不是 "Mario way" 的做法,但它可能会让您更接近某种感觉。
不确定这本身是否构成答案,但我决定为平台游戏实现我自己的物理学。
对于可能面临与我类似问题的任何人,我建议您也这样做。在我的另一个游戏 Piston Flip 中,我使用了 Spritekit 物理,因为该游戏包含物理体的一些变化,我从来不需要完全 重新创建相同的物理交互两次.因此,如果您制作的东西需要稍微复杂一点的物理学并且不需要精确复制,请使用 spritekit 物理学。
现在,如果您需要像平台游戏这样的精确度,我建议您自己实现。我使用 this tutorial 作为起点并从那里进行定制。抛开令人恼火的初始实施不谈,我现在真的很高兴我能如此准确地控制一切。
所以我有一个与地面碰撞的动态矩形物理体(玩家),它不是动态的,也是一个矩形。
每当两者发生碰撞时,玩家的物理体都会略微穿过地面,然后弹回。我可以通过使用 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 作为传感器。传感器是 SKNode
或 SKSpriteNode
(在下图中),具有不受重力影响并固定到 parent 节点的动态 SKPhysicsBody
。 body 不应与任何东西发生碰撞,而只是通过其 contactTestBitMask
响应与其他物理体的接触。它看起来像这样。
这可能不是 "Mario way" 的做法,但它可能会让您更接近某种感觉。
不确定这本身是否构成答案,但我决定为平台游戏实现我自己的物理学。
对于可能面临与我类似问题的任何人,我建议您也这样做。在我的另一个游戏 Piston Flip 中,我使用了 Spritekit 物理,因为该游戏包含物理体的一些变化,我从来不需要完全 重新创建相同的物理交互两次.因此,如果您制作的东西需要稍微复杂一点的物理学并且不需要精确复制,请使用 spritekit 物理学。
现在,如果您需要像平台游戏这样的精确度,我建议您自己实现。我使用 this tutorial 作为起点并从那里进行定制。抛开令人恼火的初始实施不谈,我现在真的很高兴我能如此准确地控制一切。