Search code examples
objective-cswiftxcodesprite-kitskcropnode

How to crop out a SKLabelNode from a SKShapeNode?


enter image description here

I want to get the effect show above using the steps below.


Basically, it consists of a background image SKSpriteNode of

enter image description here

And I add a red color SKShapeNode on top of it

enter image description here

The I want to cut out the SKLabel Node off of that Red ShapeNode.

enter image description here

I have a code that could fake this effect. But, if you move the shape node, then the gimmick will be exposed.

class GameScene: SKScene {

    override func didMove(to view: SKView) {
        let baseNode = SKSpriteNode(imageNamed: "step1")
        baseNode.zPosition = 0
        baseNode.position = CGPoint(x:0,y:100)

        let shapeNode = SKShapeNode(rect: CGRect(origin: CGPoint(x:-155, y:-15), size: baseNode.size))
        shapeNode.fillColor = .red
        shapeNode.zPosition = 1
        addChild(shapeNode)

        let labelNode = SKLabelNode(text: "Hi")
        labelNode.fontColor = .white
        labelNode.fontName = "Arial"
        labelNode.fontSize = 185
        labelNode.zPosition = 2

        let cropNode = SKCropNode()
        cropNode.addChild(baseNode)
        cropNode.maskNode = labelNode
        cropNode.zPosition = 1
        addChild(cropNode)
    }
}

And If I try blend modes, it doesn't take me anywhere.]

class GameScene: SKScene {

    override func didMove(to view: SKView) {
        let baseNode = SKSpriteNode(imageNamed: "step1")
        baseNode.zPosition = 0
        baseNode.position = CGPoint(x:0,y:100)
        addChild(baseNode)

        let shapeNode = SKShapeNode(rect: CGRect(origin: CGPoint(x:-155, y:-15), size: baseNode.size))
        shapeNode.fillColor = .green
        shapeNode.zPosition = 1
        addChild(shapeNode)

        let labelNode = SKLabelNode(text: "Hi")
        labelNode.fontColor = .red
        labelNode.fontName = "Arial"
        labelNode.fontSize = 185
        labelNode.zPosition = 2
        labelNode.blendMode = .subtract
        shapeNode.addChild(labelNode)

        let circle = SKShapeNode(circleOfRadius: 40)
        circle.position = CGPoint(x:0,y:40)
        circle.fillColor = .green
        circle.blendMode = .subtract
        circle.zPosition = 3
        shapeNode.addChild(circle)
    }
}

enter image description here


Solution

  • If you invert your thinking, this will be much easier.

    Put the Red layer at the back/bottom. Lowest zPosition. Let's say -1.0 for this example.

    Put the picture on top of this, at a zPosition of 0.0

    Put the letter above, at a zPostion of 1.0

    So, from the screen of the iPhone, it's like this:

    • Screen
    • Letter
    • Picture
    • Red BG

    You want to use the letter to mask out the picture.

    Having done that, whenever you move the letter, it reveals the contents beneath itself, from the picture. Everything else is RED.