5

I'm trying to blur a SKShapenode in my program. However, I want the shapenode to blur progressively, with a duration of about 1 second. How do I achieve that? The current code blurs it instantly.

func generateAnimation() {

var blurAction : SKAction = SKAction.runBlock{
   //the method below returns a shapeNode
    var circle = self.generateImage()
    var effect : SKEffectNode = SKEffectNode()
    var filter : CIFilter = CIFilter(name:"CIGaussianBlur")
    filter.setValue(10, forKey: "inputRadius")
    effect.filter = filter
    effect.addChild(circle)
    self.addChild(effect)           
}
nhgrif
  • 61,578
  • 25
  • 134
  • 173
Raghu
  • 361
  • 1
  • 2
  • 11

3 Answers3

6

Implement the update method in your SKScene subclass (or delegate). Then, over the course of one second, run this line again each time your update method is called:

filter.setValue(10, forKey: "inputRadius")

Except instead of passing the value 10, interpolate between 0 and 10 based on the elapsed time.

You might find that re-rendering a blur every frame makes it hard to keep a smooth frame rate. So you might consider faking it instead. Make two nodes, one of which has the blur effect, and use fadeInWithDuration/fadeOutWithDuration actions to fade in the blurred node and fade out the unblurred node.

rickster
  • 124,678
  • 26
  • 272
  • 326
1

I agree with @rickster. In the apple spritekit demo they used this to simulate blinking of the lights (in which the lights fade out from the screen --> "blur" the light).

- (SKSpriteNode *)newLight
{
    SKSpriteNode *light = [[SKSpriteNode alloc] initWithColor:[SKColor yellowColor] size:CGSizeMake(8,8)];

    SKAction *blink = [SKAction sequence:@[
                                       [SKAction fadeOutWithDuration:0.25],
                                       [SKAction fadeInWithDuration:0.25]]];
    SKAction *blinkForever = [SKAction repeatActionForever:blink];
    [light runAction: blinkForever];

    return light;
}

You can modify the behaviour of "blinkForever" to suit your case.

user1872384
  • 6,886
  • 11
  • 61
  • 103
0

Here you go mate, Swift4 SpriteKit:

let ITEM_MAX_BLUR_AMOUNT: CGFloat = 20
let ITEM_MIN_BLUR_AMOUNT: CGFloat = 0
let ITEM_FOCUS_DURATION: TimeInterval = 0.2

let effectNode: SKEffectNode = SKEffectNode()

effectNode.filter = CIFilter = CIFilter(name: "CIGaussianBlur")
effectNode.shouldEnableEffects = true
addChild(effectNode)

let focusAction = SKAction.customAction(withDuration: ITEM_FOCUS_DURATION, actionBlock: { (node : SKNode!, elapsedTime : CGFloat) -> Void in

    let fraction = CGFloat(elapsedTime / CGFloat(ITEM_FOCUS_DURATION))
    let deltaBlur: CGFloat = ITEM_MAX_BLUR_AMOUNT-ITEM_MIN_BLUR_AMOUNT
    let blurAmount = ITEM_MAX_BLUR_AMOUNT-deltaBlur*fraction
    (node as! SKEffectNode).filter!.setValue(blurAmount, forKey: kCIInputRadiusKey)

})

focusAction.timingMode = .easeIn
effectNode.run(focusAction)
Geoff H
  • 3,107
  • 1
  • 28
  • 53