我正在评估 iOS SpriteKit 物理引擎,为了测试,我创建了一个包含两个 circle-shaped 节点的 Xcode 的简单场景:
两个节点都具有圆形和 5 千克质量的物理体。我用SKPhysicsJointSpring
连接两个节点。这是整个设置(在viewDidLoad()
中):
let path = NSBundle.mainBundle().pathForResource("MyScene", ofType: "sks")!
let scene = NSKeyedUnarchiver.unarchiveObjectWithFile(path) as! SKScene
let border = SKPhysicsBody(edgeLoopFromRect: scene.frame)
border.restitution = 0;
border.friction = 0;
scene.physicsBody = border
let player = scene.childNodeWithName("player")! // large ball
let tail1 = scene.childNodeWithName("tail1")! // smaller ball
player.physicsBody!.usesPreciseCollisionDetection = true
tail1.physicsBody!.usesPreciseCollisionDetection = true
let spring1 = SKPhysicsJointSpring.jointWithBodyA(player.physicsBody!, bodyB: tail1.physicsBody!, anchorA: player.position, anchorB: tail1.position)
spring1.damping = 1
spring1.frequency = 3
scene.physicsWorld.addJoint(spring1)
spriteKitView.presentScene(scene)
注意:场景编辑器中的重力设置为(0,0)。
当我移动较大的节点时(例如,通过使用 touchesBegan()捕获触摸并将节点的位置设置为触摸位置),另一个根据弹簧参数进行跟随。
但是,如果我足够快地移动节点,使弹簧力变得极端,则弹簧收缩时两个节点都会重叠。我期待它们彼此冲突,因为它们的collisionBitMask
默认设置为-1(所有位都设置)。我已启用usesPreciseCollisionDetection
但效果仍然可见。
当我在场景周围添加边缘循环时,它们会按预期与该边缘碰撞。与具有物理主体(但没有连接关节)的其他节点相同。
我的印象是弹簧的存在以某种方式使引擎忽略与关节连接的节点之间的碰撞。还有其他人观察过这个吗?我忘了什么吗?或者这是否按预期工作?
1 回答
试图回答我自己的问题。
我发现其他关节(例如
SKPhysicsJointLimit
)也会禁用连接节点之间的冲突。我唯一的结论是,所有 SpriteKit 关节都以某种方式将两个对象视为一个,其中碰撞被认为是不合需要的。虽然在我的应用程序中我更喜欢启用碰撞。也许我应该在 Apple 开发人员的反馈中提交增强功能。到目前为止,我的解决方法包括:
通过将
SKFieldNode.springField
加上SKFieldNode.dragField
作为子节点添加到精灵节点来创建弹簧行为。亲:作为孩子,这些字段会自动跟随父母的位置; Con:这会占用fieldBitMask
的 2 个宝贵位,这对这些节点的数量设置了自然限制。在每一帧手动施加一些弹簧阻力。 Pro:不浪费
fieldBitMask
,Con:手动计算弹簧阻力。所以我倾向于选择 2。
总结:如果您希望在保持碰撞的同时在两个节点之间进行弹簧行为,请手动执行力并且不要使用关节。