11
votes

I've created a SpriteKit Scene with physics bodys. This is working quite well. I'm also scrolling the scene around, using the Apple best practice with a "camera node".

My scenes node tree is like that:

Scene
|- World
   |- Camera node
   |- Game nodes with physics bodys

My Problem is, during the game I create new nodes with new joints (mostly fixed joints) dynamically. At that point, the world node has a different position than in the beginning (eg.: at start (0,0), during the game (1000,500)..) Now, the anchorpoint for the fixed joints is not at the position I want it to, it's somewhere in the scene.

I assume, the coordinate system of the scene is different to the coordinate system of the physics engine.

For the anchor Point, I use the following conversion:

[world.scene convertPoint:node.position fromNode:node.parent];

I want to set the anchorpoint at the position of "node". After moving the world node, the calculation of the anchorpoint is not working anymore.

Thanks for your help!

Greetz - Nekro

Update:

Code to center scene on the Player

- (void)centerOnNode:(SKNode*)node {
    CGPoint cameraPositionInScene = [node.scene convertPoint:node.position fromNode:node.parent];
    node.parent.position = CGPointMake(node.parent.position.x - cameraPositionInScene.x, node.parent.position.y - cameraPositionInScene.y);
}
1
Try adding your Game nodes to the World instead of the Camera node. I implemented a test app and adding a joint after moving the world/camera worked as expected.0x141E
@0x141E Sorry for that, I updated my text. I the game nodes are added in parallel to the camera node, not as children of the camera node. The strange thing is, if I activate the visualization of physics for my SpriteKit scene, sporadically joints appear connected to my central player node.. I already set a breakpoint to the only function in which I create joints, but it looks like this path is never run for this "ghost-joints"...Nuker
Just to ensure : Your physics bodies are connected using the Scene Coordinates ? and not the Node's ?ColdSteel
@Nuker it looks like your conversion from world coordinates to scene coordinates is correct but...I suggest you try [world convertToPoint:node.position toNode:world.parent]. Also, make sure node.position is in world coordinates (it should be) and the collisionBitMasks are set so the two bodies don't collide with each other.0x141E
@0x141E I will try the different conversion you mentioned. Yes, the nodes are in world coordinates. The world node is moved to center on the Player node. The collisionBitMask is set, because my "figures" are build from the same kind of "blocks". Otherwise, I can't establish any collision because of the lack of the bitmask(only 20-something different bitmasks). I have a lot of (200++) different "figures" build from the same type of blocks, also the player "figure" is build from those blocks. How else could I allow collisions between those "figures" but not between blocks from the same "figure"?Nuker

1 Answers

1
votes

There are two requirements to using joints with SpriteKit physics:

  1. Define the joints in world (scene) space.
  2. Don't move the world.

From your question and comments, it sounds like you've got #1 right: When the joint is between nodes that aren't direct children of the scene, you need to convert coordinates to scene space before using them to define a joint.

However, SpriteKit physics doesn't handle it well when you try to move the root coordinate system. So, implementing a "camera" by moving the world causes trouble for the joints. Instead:

  • If you can afford to target only iOS 9.0 / OS X 10.11 / tvOS 9.0 and up, use SKCameraNode instead of moving the world. It's easier, too!

    (If you're wondering about whether you can support only iOS 9, check the adoption rate statistics, and compare to your development schedule... if you won't be shipping for awhile, iOS 9 might be the "-1" OS version by the time you're done. Remember also there's a high correlation between enthusiastic customers and early adopters.)

  • If you're supporting iOS 8 / OS X 10.10 still, try adding an extra layer to your scene: fake a camera by moving a node that is a child of your scene and the parent of all your game content.