如何将可设置动画的CIFilter添加到我的SKScene中

时间:2017-07-30 16:25:28

标签: ios swift animation cifilter

我真的希望在我的SKScene中添加一个CIFilter。事实上我可以很容易地将以下内容放入didMove(to view: SKView)类的GameScene函数中:

let grayscaleFilter = CIFilter(name: "CIColorControls", withInputParameters: ["inputBrightness" : 0.0, "inputContrast" : 1.1, "inputSaturation" : 0.0])!
grayscaleFilter.name = "grayscale"
self.filter = grayscaleFilter
self.shouldEnableEffects = true

现在我的问题是尝试动画它,据我所知,有效动画CIFilters的唯一方法是使用Core Animation。我知道核心动画只能添加到CALayer,所以我在didMove(to view: SKView)类的GameScene函数中尝试了以下代码:

let grayscaleFilter = CIFilter(name: "CIColorControls", withInputParameters: ["inputBrightness" : 0.0, "inputContrast" : 1.1, "inputSaturation" : 0.0])!
grayscaleFilter.name = "grayscale"
let grayscaleAnimation = CABasicAnimation(keyPath: "filters.grayscale.inputSaturation")
grayscaleAnimation.fromValue = 0.0
grayscaleAnimation.toValue = 1.0
grayscaleAnimation.duration = 5
view.isMultipleTouchEnabled = false
view.layer.filters?.append(grayscaleFilter)
view.layer.add(grayscaleAnimation, forKey: "grayscaleAnimation")

我根本没有结果。没有动画。根本没有过滤器。有没有人知道如何以一种有效的方式做到这一点,并且任何人都可以解释为什么我当前的方法不起作用。感谢任何帮助,提前谢谢。

1 个答案:

答案 0 :(得分:0)

这是我知道的一种工作方式,仅使用SpriteKit(不使用Core Animation)。首先创建过滤器,并将其存储:

let filter = CIFilter(name: "CIExposureAdjust", withInputParameters: ["inputEV": 0])
self.filter = filter // store it
scene.filter = filter // so the whole scene will be filtered
scene.shouldEnableEffects = true

然后创建一个可更改过滤器属性的SKAction。

let duration = 1.0
let a = SKAction.customAction(withDuration: duration) { (node, elapsed) in
    let percent = elapsed / CGFloat(duration)
    // Animate inputEV from 0 to 2.5
    self.filter.setValue(percent * 2.5, forKey: "inputEV")
}
a.timingMode = .easeIn
scene.run(a)

如果您不想过滤整个场景,则可以以相同的方式使用SKEffectNode。但是,您无需将过滤器分配给场景,而是将其分配给SKEffectNode。但是,在更新过滤器的属性后,您需要在SKAction块中添加以下行:

self.myEffectNode.shouldEnableEffects = true

如果没有SKAction块中的那一行,动画将无法工作。我认为这是一个错误。不过,如果您要在整个场景上设置滤镜,则不必这样做。