我真的希望在我的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")
我根本没有结果。没有动画。根本没有过滤器。有没有人知道如何以一种有效的方式做到这一点,并且任何人都可以解释为什么我当前的方法不起作用。感谢任何帮助,提前谢谢。
答案 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块中的那一行,动画将无法工作。我认为这是一个错误。不过,如果您要在整个场景上设置滤镜,则不必这样做。