Cherrypig
Cherrypig

Reputation: 370

Fading action of SKNode() with SKCropNode() children

I have a SKNode() which has SKCropNode() children. I am able to run all kind of actions to rotate and scale my SKNode(), but when I want to use any kind of fading actions the result always is alpha 1 or alpha 0. No way of fading.

By replacing the SKCropNode() with a SKShapeNode() the fading action is working fine.

Can anyone tell my why? Isn't it possible to fade masked nodes?

import SpriteKit

class GameScene: SKScene {

let player = SKNode()
let playerSize = CGFloat(50)
let playerCrop = SKCropNode()
let playerMask = SKSpriteNode(color: SKColor.blackColor(), size: CGSizeMake(CGFloat(100), CGFloat(100)))
let playerCircle = SKShapeNode(circleOfRadius: CGFloat(100))

let playerCenterMask = SKShapeNode(circleOfRadius: CGFloat(100))
let playerCenterCrop = SKCropNode()

override func didMoveToView(view: SKView) {

    backgroundColor = SKColor.blackColor()

    player.position = CGPoint(x:CGRectGetMidX(self.frame), y:CGRectGetMidY(self.frame))
    player.alpha = 0
    addChild(player)

    playerCenterMask.lineWidth = 20        
    playerCenterCrop.maskNode = playerCenterMask

    playerMask.position.x = -playerSize
    playerMask.position.y = playerSize
    playerCircle.lineWidth = 0
    playerCircle.fillColor = SKColor.redColor()
    playerCrop.addChild(playerCircle)
    playerCrop.maskNode = playerMask

    playerCenterCrop.addChild(playerCrop)
    player.addChild(playerCenterCrop)

    // Animations
    let playerScale = SKAction.scaleTo(2.0, duration: 5)
    let playerFadeIn = SKAction.fadeInWithDuration(5)
    let playerAnimation = SKAction.group([playerScale,playerFadeIn])

    player.runAction(playerAnimation, completion: {})

}

}

Upvotes: 0

Views: 341

Answers (1)

Knight0fDragon
Knight0fDragon

Reputation: 16827

As mentioned in the comments: SKCropNode uses alpha < 0.5 to not draw. >= 0.5 to draw, and you can't set the blend mode, so it is probably doing source blend mode. Which means it is overwriting the alpha. Children afterwards get blended.

The player context is created, it draws at the given alpha, then the SKCropNode is drawn, overwriting alpha instead of blending.

Run the fade in action on your child, not your parent to get the results you are looking for.

Here is what your source looks like with changes:

import SpriteKit

class GameScene: SKScene {

    let player = SKNode()
    let playerSize = CGFloat(50)
    let playerCrop = SKCropNode()
    let playerMask = SKSpriteNode(color: SKColor.blackColor(), size: CGSizeMake(CGFloat(100), CGFloat(100)))
    let playerCircle = SKShapeNode(circleOfRadius: CGFloat(100))

    let playerCenterMask = SKShapeNode(circleOfRadius: CGFloat(100))
    let playerCenterCrop = SKCropNode()

    override func didMoveToView(view: SKView) {

        backgroundColor = SKColor.blackColor()

        player.position = CGPoint(x:CGRectGetMidX(self.frame), y:CGRectGetMidY(self.frame))
        player.alpha = 1
        addChild(player)
        playerCircle.alpha = 0
        playerCenterMask.lineWidth = 20
        playerCenterCrop.maskNode = playerCenterMask

        playerMask.position.x = -playerSize
        playerMask.position.y = playerSize
        playerCircle.lineWidth = 0
        playerCircle.fillColor = SKColor.redColor()
        playerCrop.addChild(playerCircle)
        playerCrop.maskNode = playerMask
        playerCenterCrop.addChild(playerCrop)
        player.addChild(playerCenterCrop)

        // Animations
        let playerScale = SKAction.scaleTo(2.0, duration: 5)
        let playerFadeIn = SKAction.fadeInWithDuration(5)
        let playerAnimation = playerScale

        player.runAction(playerAnimation, completion: {})
        playerCircle.runAction(playerFadeIn, completion: {})

    }

}

Upvotes: 1

Related Questions