sprite-kitskspritenodeskshapenode

Adding SKShapeNode as Child to SKSpriteNode


Using SpriteKit, I'm trying to create a rectangle as a background, with a second rectangle 25% of the size of the background and position it at the bottom of the background. (so the lower 25% is blue, and the upper 75% is dark grey)

This is my set up:

screenWidth = size.width   //312
screenHeight = size.height //390

func createSky(){
    let sky = SKSpriteNode(color: SKColor.darkGray, size: CGSize(width: screenWidth, height: screenHeight))
    print("Sky: ", sky.frame)
    addChild(sky)
}

func createGround(){
    let ground = SKShapeNode.init(rectOf: CGSize(width: screenWidth, height: screenHeight / 4))
    ground.fillColor = SKColor.blue
    print("Ground: ", ground.frame )
    sky.addChild(ground)
}

For some reason, ground.frame is printing Ground: (-157.35, -50.1, 314.7, 100.2). Why is this? Shouldn't the last 2 figures be 312, 97.5?

I've tried various .positions and .anchorPositions but I still can't get the SKShapeNode to sit correctly within the SKSpriteNode.

Eventually the Shape will be more complex which is why I'm not using Sprite for the second one. What am I missing?


Solution

  • So what it looks like from your code is that you are trying to create a shapeNode and then position it inside your SKSpriteNode. Most of it you got right, you just did the positioning code incorrectly.

    When you add a child to a node, that child uses the parent node as its origin point for reference. So if you tell the child node to be -50 X and 150 Y, that child node will be -50 X and 150 Y from the center point of its parent node.

    When I do child nodes (especially ones that have a ton of similarities to the parent node) I like to reference the parent node for positioning, width, and height. I don't know if it might be bad practice, but its what I've done for two years now.

    This is how I would have done it:

    var sky = SKSpriteNode()
    var ground = SKShapeNode()
    
    func createSky() {
        sky = SKSpriteNode(color: SKColor.darkGray, size: CGSize(width: self.frame.size.wdith, height: self.frame.size.height))
        // self.frame.size.width/self.frame.size.height calls its info from the ViewController, which is tied directly to your screen size (unless otherwise changed) 
        sky.position = CGPoint(x: 0,y: 0)
        self.addChild(sky)
    }
    
    func createGround() {
        ground = SKShapeNode((rectOf: CGSize(width: sky.width, height: sky.height * 0.25))
        ground.position = CGPoint(x: 0, y: sky.position.y - (ground.size.height / 1.5))
    }