I still play with learning SpriteKit on iOS and read a lot and experiment a lot. I am confused by what I found * regarding coordinates, frames, and child nodes.
Consider this piece of code in which I am trying to draw a green box around my spaceship sprite for debugging purposes:
func addSpaceship() { let spaceship = SKSpriteNode.init(imageNamed: "rocketship.png") spaceship.name = "spaceship" // VERSION 1 spaceship.position = CGPointMake(CGRectGetMidX(self.frame), CGRectGetMidY(self.frame)) let debugFrame = SKShapeNode(rect: spaceship.frame) debugFrame.strokeColor = SKColor.greenColor() spaceship.addChild(debugFrame) // VERSION 2 // spaceship.position = CGPointMake(CGRectGetMidX(self.frame), CGRectGetMidY(self.frame)) spaceship.setScale(0.50) self.addChild(spaceship) }
If I add a spacecraft sprite set with a line labeled “VERSION 1” above, I get the following:

which is clearly wrong. But if I comment on the line labeled “VERSION 1” above and instead use the line labeled “VERSION 2”, I get what I want:

Please note that the actual code for the lines marked “Version 1” and “Version 2” is identical: spacehip.position = CGPointMake (CGRectGetMidX (self.frame), CGRectGetMidY (self.frame))
So why does it matter when I set the position of the sprite of a spaceship?
In my way of thinking, the position of the spacecraft sprite is not related to the placement of the debugFrame, because debugFrame is a child of the spacecraft sprite, and therefore its coordinates should refer to the frame of the spacecraft sprite - on the right
Thanks WM
* This is somewhat related to the question I asked yesterday:
On SpriteKit on iOS, scaling a textured sprite creates the wrong frame?
but a) I understand that now, and b) it is completely different that he deserves his own question.
UPDATE:
Hmmm - thanks guys for the ideas below, but I still don’t understand, and maybe this will help.
I changed my code to print relavant positions and frames:
func addSpaceship() { let spaceship = SKSpriteNode.init(imageNamed: "rocketship.png") spaceship.name = "spaceship" println("Spaceship0 Pos \(spaceship.position) Frame = \(spaceship.frame)") // VERSION 1 (WRONG) spaceship.position = CGPointMake(CGRectGetMidX(self.frame), CGRectGetMidY(self.frame)) println("Spaceship1 Pos \(spaceship.position) Frame = \(spaceship.frame)") let debugFrame = SKShapeNode(rect: spaceship.frame) println("DEBUG Pos \(debugFrame.position) Frame = \(debugFrame.frame)") debugFrame.strokeColor = SKColor.greenColor() spaceship.addChild(debugFrame) // VERSION 2 (RIGHT) // spaceship.position = CGPointMake(CGRectGetMidX(self.frame), CGRectGetMidY(self.frame)) // println("Spaceship2 Pos \(spaceship.position) Frame = \(spaceship.frame)") spaceship.setScale(0.50) self.addChild(spaceship) }
Then I ran in both directions, getting these results. Since I understand version 2, let's get started there.
Running the code "VERSION 2 (RIGHT)", I got:
Spaceship0 Pos (0.0,0.0) Frame = (-159.0,-300.0,318.0,600.0) DEBUG Pos (0.0,0.0) Frame = (-159.5,-300.5,319.0,601.0) Spaceship2 Pos (384.0,512.0) Frame = (225.0,212.0,318.0,600.0)
The spaceship node starts by default its position in the lower left corner of the screen (Spaceship0). Its frame is also expressed through its reference point (in the center), set in the lower left corner of the screen, therefore, negative numbers for the beginning of its rectangular frame.
Then a debug frame is created with the default position of 0, 0, and its frame is set to the same as that of the spacecraft.
Then the code (Spaceship2) moves the spacecraft node to a position in the coordinates of the view (384.0, 512), and its beginning of the frame is moved by adding a new position to the old one (i.e. 384 + -159 = 225).
Things are good.
Unfortunately, I still do not get version 1.
When I run "VERSION 1 (WRONG)" code, I get
Spaceship0 Pos (0.0,0.0) Frame = (-159.0,-300.0,318.0,600.0) Spaceship1 Pos (384.0,512.0) Frame = (225.0,212.0,318.0,600.0) DEBUG Pos (0.0,0.0) Frame = (0.0,0.0,543.5,812.5)
As above, the spaceship node starts by default its position in the lower left corner of the screen (Spaceship0). Its frame is also expressed through its reference point (in the center), set in the lower left corner of the screen, therefore, negative numbers for the beginning of its rectangular frame.
Then the code (Spaceship1) moves the spacecraft node to a position in the coordinates of the view (384.0, 512), and its beginning of the frame is moved by adding a new position to the old origin (i.e. 384 + -159 = 225).
Then a debug frame is created with the default position of 0, 0, and its frame has a strange width (543.5) and a strange height (812.5). Since I initialize debugFrame.frame with spacehip.frame (I think the default initializer does this), I expect the new debugFrame.frame to be the same as the spacecraft frame, but it is not! The values of the width and height of the debugging frame are apparently associated with the addition of the actual width and height to the beginning of the frame of the spacecraft node (543.5 = 225 + 318.5). But if so, then why is the t-shaped direct origin still 0, 0 and not the same addition (225.0 + 0 = 225.0) ???
I do not understand.