Reputation:
How can I get the absolute position of the _childNode in this example:
I have a parent: _worldNode
I have a child: _childNode
I set the _childNode position to 10,10.
I rotate _worldNode 90 degrees.
Now, when I query the _childNode position I am given 10,10. Naturally this is no longer the case. Even doing [_childNode calculateAccumulatedFrame] gives me a CGRect at 10,10.
Any ideas how to return the correct position (-10,10)? Here's the code from my test (just put into init, all logs return 10,10).
CGRect screenRect = [[UIScreen mainScreen] bounds];
CGFloat screenWidth = screenRect.size.width;
CGFloat screenHeight = screenRect.size.height;
CGPoint screenCentre = CGPointMake(screenHeight/2.0,screenWidth/2.0);
_worldNode = [SKNode node];
_worldNode.position = screenCentre;
[self addChild:_worldNode];
_childNode = [[SKSpriteNode alloc] initWithColor:[UIColor redColor] size:CGSizeMake(10, 10)];
_childNode.position = CGPointMake(10, 10);
[_worldNode addChild:_childNode];
NSLog(@"position of child pre rotation %f, %f", _childNode.position.x, _childNode.position.y);
_worldNode.zRotation = 90;
NSLog(@"position of child after rotation %f, %f", _childNode.position.x, _childNode.position.y);
CGPoint position = _childNode.position;
[_childNode convertPoint:position toNode:_worldNode];
NSLog(@"position of child after conversion %f, %f", position.x, position.y);
CGRect groupRect = [_childNode calculateAccumulatedFrame];
CGPoint newPosition = CGPointMake(groupRect.origin.x + (groupRect.size.width / 2), groupRect.origin.y + (groupRect.size.height / 2));
NSLog(@"position of child based on frame %f, %f",newPosition.x,newPosition.y);
Many thanks in advance, Ian
Upvotes: 1
Views: 4429
Reputation: 20274
There are a lot of mistakes in your code.
1-
_worldNode.position = screenCentre; //This places the node at the SKScene centre
should be
_worldNode.position = CGPointZero; //This places the node at the origin.
The SKScene's default coordinate system has the origin at the lower left corner.
2-
_worldNode.zRotation = 90;
should be
_worldNode.zRotation = M_PI_2;
The zRotation is measured in radians, not degrees.
3-
Look at the two NSLogs in the code:
NSLog(@"position of child after rotation %f, %f", _childNode.position.x, _childNode.position.y); // - 1
CGPoint position = _childNode.position;
[_childNode convertPoint:position toNode:_worldNode]; //returns a CGPoint, where are you storing it?
NSLog(@"position of child after conversion %f, %f", position.x, position.y); // - 2
The position
variable is not actually converted. The method returns another CGPoint which in turn will need to be logged.
However, this will return the wrong position as _childNode.position
stores it's position relative to it's parent (i.e. _worldNode
) and hence using convertPoint
to _worldNode
will convert (10,10) on the _childNode to _worldNode, making it (20,20).
Try using this line instead:
CGPoint position = [self convertPoint:_childNode.position fromNode:_worldNode];
NSLog (@"Position: %@", [NSValue valueWithCGPoint:position]);
This will give you the position w.r.t the Scene, which is what you were aiming at.
Upvotes: 1
Reputation: 32459
In short: rotation doesn't change node's position.
SKSpriteNode
's position
returns a position of an anchorPoint
for that node.
When you rotate SKSpriteNode
, it's rotating over its anchorPoint
, so node's anchorPoint
remains in the same position as it was before rotation. That's why you always get (10, 10)
Upvotes: 1