6

I have fairly well developed SpriteKit game I'm working on, added some code to add a new SKSpriteNode to the Scene, (same as I have done dozens of other places in the code, but for some reason this time it is just ignoring the position I have set for the node, I have tried it by explicit .position = CGPointMake(x,y) and trying the [node setPosition:CGPointMake(x,y)]

Neither work... the node does get added to the scene, but ALWAYS at 0,0, no matter what I do, have checked both the x and y to make sure they are valid and in the range of the scene, and tried to use explicit floats etc, and it doesn't matter what I do, this node always shows up at 0,0 and it makes absolutely no sense. I am doing everything the same I am doing with dozens of other nodes over the course of game play but this node just won't show up anywhere but 0,0 no matter what I do:

int width = 64;
SKSpriteNode *node = [[SKSpriteNode alloc] initWithColor:[SKColor grayColor] size:CGSizeMake(width,25)];
node.physicsBody = [SKPhysicsBody bodyWithRectangleOfSize:node.size];
node.physicsBody.dynamic = NO;
node.physicsBody.categoryBitMask=nodeCategory;
node.name=@"node";
node.position = CGPointMake(200,250);
//Have also tried [node setPosition:CGPointMake(200,250);
[self addChild:node];

I am completely at a loss here, I've tried adding .0 to the inputs to the CGPointMake to ensure they are handled as floats nothing... No matter what I do with this node, when it is added to the scene it always defaults to the 0,0 position, and I am frustrated, I am adding all sorts of nodes without incident, just something about this node add that is just not working and can't figure out what is different or why.

Speckpgh
  • 3,332
  • 1
  • 28
  • 46
  • 1
    try: without physics body / set position before assigning body / create subclass of sprite and override setPosition and set a breakpoint to verify no other code is setting position – CodeSmile Jan 26 '14 at 23:33
  • Taking out the line "node.physicsBody = [SKPhysicsBody bodyWithRectangleOfSize:node.size];" seems to alleviate the problem, but I don't understand why.. I am creating a physics body with size of every node I create, and have no issues... I don't understand why in this instance this is causing it to ignore position... Very very odd. – Speckpgh Jan 26 '14 at 23:40
  • it could be squeezed in other bodies thus moved by contact resolver, or it might not allow changing position because of dynamic=no, and you could try an edge loop/chain body instead because those are truly static bodies – CodeSmile Jan 26 '14 at 23:46
  • The location I am adding it isn't in contact with anything, and while the removal of the physics body size declaration does show the object properly, now that its there, it doesn't properly interact with anything on the screen, because well, the physics engine thinks it has a body of no size... so while it solved the position issue, it now leaves me with an object that nothing will interact with. – Speckpgh Jan 26 '14 at 23:49
  • So, I commented out the physics body, to get the node to appear where I wanted it, then after the add to parent I added a: [node setPhysicsBody: [SKPhysicsBody bodyWithRectangleOfSize:node.size]]; and this seems to work but holy hell is this a kludge from hell that I am dealing with an order of operations to make this work... this doesn't make sense to me. – Speckpgh Jan 26 '14 at 23:58
  • I have to conclude that since it properly works without the physics body set that your suggesting about contact resolver is thinking it would be in contact with something or something along those lines and refusing to place it where I want... So, adding the physics body after adding the node to the screen resolves it. Is there any way to check/track the contact resolver to see if its the root cause? Nothing was in the position I was attempting to place the node, but I can't argue that removing the physics body allowed it to be placed there. – Speckpgh Jan 27 '14 at 00:15
  • I have the same issue when creating a new node with the contact delegate. When setting up the scene it doesn't matter what order the position and physics body are in, but when adding a node in the contact callback I need to set position first. Have you filed a bug? I commented here as well. http://stackoverflow.com/questions/20359060/skspritenode-position-changes-to-0-0-for-no-reason – macshome Jan 27 '14 at 04:38
  • Setting the position prior to the PhysicsBody and moving all that setup prior to the addChild also seems to work... clearly something in the order of operations is causing this issue... Which may have a reason for happening, but lord knows I have no idea what it would be. – Speckpgh Jan 27 '14 at 05:16
  • try your code above again but set dynamic=no only after changing position – CodeSmile Jan 27 '14 at 07:33
  • Isn't it possible to check if node A collides with node B? If so then I suppose you could make a small `NSLog` check that returns the names of two nodes when/if they collide. – crenfrow Jan 27 '14 at 13:34
  • The ordering thing seems to be a bug. In the setup method for my SKScene I can create my nodes and physics bodies in any order. Any additional nodes that are added need to have the physics set AFTER the position. A bit of a pain since my class returns SKSpriteNodes that are fully configured as that let me isolate the setup in the class. – macshome Jan 27 '14 at 18:48
  • I'm having the exact some problem. Has anyone found a more elegant solution? – NMunro Feb 14 '14 at 02:06

1 Answers1

3

I've been having this same issue. I have a subclass of SKSpriteNode that most of my in-game nodes use as a superclass. I've added this method, which I use whenever I run into the positioning problem:

- (void)refreshPhysicsBodyAndSetPosition:(CGPoint)position {

    /*
     * Weird thing here: if I just set the position of these nodes, they
     * end up at position (0,0). However, if I remove the physics body, set
     * the position, and then re-add the physics body, the nodes are
     * placed correctly.
     */

    SKPhysicsBody *tempPhysicsBody = self.physicsBody;
    self.physicsBody = nil;

    // Position and re-add physics body
    self.position = position;
    self.physicsBody = tempPhysicsBody;
}

Obviously, this isn't a real answer to the issue, but it's a workaround that may help some of you. I have a question opened on the Apple Developer forum, which you can view here:

https://devforums.apple.com/thread/222332

Hoping I hear back soon.

harrisonlee
  • 5,068
  • 4
  • 21
  • 20