Search code examples
iosswiftsprite-kit

Node positioning issue in Swift 3


I'm just starting out looking into Swift 3 - never coded before so I'm completely new to it all. Been looking at a really basic Node tutorial and have the following code:

class GameScene: SKScene {

    override func didMove(to view: SKView) {

        // SKLabelNode
        var exampleLabelNode = SKLabelNode(fontNamed: "Helvetica")
        exampleLabelNode.text = "Example Label Node!"
        exampleLabelNode.fontSize = 30
        exampleLabelNode.fontColor = SKColor.white
        exampleLabelNode.position = CGPoint(x: self.frame.size.width / 2, y: self.frame.size.height * 0.75)
        self.addChild(exampleLabelNode)

        // SKSpriteNode
        var exampleSpriteNode = SKSpriteNode(imageNamed: "myImage")
        exampleSpriteNode.size = CGSize(width: 180, height: 180)
        exampleSpriteNode.anchorPoint = CGPoint(x: 0.5, y: 0.5)
        exampleSpriteNode.position = CGPoint(x: self.frame.size.width / 2, y: self.frame.size.height * 0.25)
        exampleSpriteNode.zPosition = 100
        exampleSpriteNode.name = "exampleName"
        self.addChild(exampleSpriteNode)

    }

}

It's meant to position exampleLabelNode centre and 3/4 at the top of the screen and exampleSpriteNode 1/4 at the bottom of the screen.

However its positioning exampleSpriteNode 3/4 to the top of the screen and half off to the right with the exampleLabelNode positioned off the screen.

The tutorial is for Swift 2, so is the positioning syntax etc different for Swift 3?


Solution

  • This is happening because the default scene anchorPoint is (0.5, 0.5) meaning the centre of the scene. That's also the default anchorPoint for any node. That makes the point (x: 0, y: 0) at the centre of the scene.

    I suggest you read more about this or ask questions to get a better understanding of it if you're having trouble.

    Official Apple Docs

    SKSpriteNode anchorPoint

    SKScene anchorPoint

    Note: The docs for the SKScene is incorrect when it says that the default value is (0, 0).

    To solve your issue, you can add this line to the beginning of your didMove(to view):

    self.anchorPoint = CGPoint(x: 0, y: 0)
    

    This sets the scene anchorPoint to the bottom left of the scene, which used to be how it was (The tutorial is outdated).

    Alternatively, you could redo the sprite placement now that you know how anchorPoint works. I suggest this because I find building games to be easier when building the scene from the centre outwards rather than from the bottom left corner.