Reputation: 748
I am evaluating the iOS SpriteKit physics engine, and for a test I have created a simple scene with Xcode that contains two circle-shaped nodes:
Both nodes have physics bodies of circular shape and 5 kg of mass.
I am connecting both nodes with a SKPhysicsJointSpring
. Here is the entire setup (in 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)
Note: The gravity is set to (0,0) in the scene editor.
When I move the bigger node (say, by capturing touches with touchesBegan() and setting the node's position to the touch position), the other follows according to spring parameters.
However, if I move the node fast enough, so that the spring forces become extreme, both nodes overlap when the spring is contracting. I am expecting them to collide with each other since their collisionBitMask
is by default set to -1 (all bits set). I have enabled usesPreciseCollisionDetection
but the effect is still visible.
When I add an edge loop around the scene they do collide with that edge as expected. Same with additional nodes that have a physics body (but no joints attached).
I have the impression that the presence of the spring somehow makes the engine ignore collisions between nodes that are connected with joints. Did anyone else observe this, too? Did I forget anything? Or is this working as intended?
Upvotes: 4
Views: 354
Reputation: 748
Attempting to answer my own question.
I found out that other joints (such as SKPhysicsJointLimit
) disable collision between the joined nodes as well. My only conclusion is that all SpriteKit joints somehow consider two objects as one, where collisions are deemed undesirable. Though in my app I would prefer to have collisions enabled. Maybe I should file an enhancement at Apple developer feedback.
So far my workarounds include:
SKFieldNode.springField
plus a SKFieldNode.dragField
as children to the sprite node. Pro: as children these fields automatically follow their parent position; Con: this spends 2 precious bits of fieldBitMask
which puts a natural limit to the number of such nodes.fieldBitMask
, Con: compute spring + drag forces manually.So I tend to favor option 2.
To summarize: If you want spring behaviour between 2 nodes while maintaining collisions, implement forces manually and do not use a joint.
Upvotes: 2