SpriteKit Physics Joints corrupt for moving scene
Asked Answered
M

1

12

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);
}
Myrticemyrtie answered 27/1, 2016 at 8:10 Comment(12)
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.Castellany
@Castellany 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"...Myrticemyrtie
Just to ensure : Your physics bodies are connected using the Scene Coordinates ? and not the Node's ?Funchal
@Myrticemyrtie 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.Castellany
@Castellany 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"?Myrticemyrtie
I suggest you add view.showsPhysics = YES; to didMoveToView and post a screenshot of the scene after you move the player (to another part of the world) and add a joint. Setting showsPhysics to YES will display outlines of all physics bodies and joints in the scene.Castellany
Today evening I will try it and post a screenshot. I already activated that feature, that's when I saw this "ghost-line" from a sudden joint which appeared after moving. As I told, I am loading new nodes on demand while the player is moving, but the creation of the nodes is always the same procedure, so there is no difference from the initial creation and the "on-demand-creation"..Myrticemyrtie
Did you examine the joint's anchor point (after converting the node's position to scene coordinates)? Since the point must be in scene coordinates, the point should be relative to the scene's anchor point. For example, if your node is in the center of the view and your scene's anchor point is (0.5, 0.5), the joint's anchor point should be (0, 0).Castellany
Yesterday I played a little bit with the code, but don't have a clue at the moment.. the point convertion you mentioned didn't work, the coordinates were totally wrong. I think my conversion to scene coordinates is OK, this method is also mentioned in the Apple Docs. But still, something is wrong. At a certain point, I can't move my player character anymore. It seems like invisible forces block my character and sometimes the nodes of my player figure are jumping and deformed, just like huge forces are applied to them..........Myrticemyrtie
I suggest you post the code that centers the player in the scene and connects the two nodes. If the player and a node are connected by a joint and the two objects are colliding, the player/node will appear to jump randomly.Castellany
I will try to take a short video which will describe my problem the best. To center the world node, I use the following code (I think, also from Apple Docs..) - (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); }Myrticemyrtie
You should add code to your question instead of pasting it in a comment. That code (from Apple's doc) is correct, but what about the code that adds the joints?Castellany
V
1

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.

Vicissitude answered 5/2, 2016 at 18:36 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.