SKEffectNode 将不会在 Swift 中使用自定义 CIFilter

SKEffectNode will not use custom CIFilter in Swift

我正在尝试将 CIFilter 子类化以用于 SpriteKit 游戏,如 iOS Games by Tutorials 一书中所述。我创建了继承自 CIFilter 的子类,它有一个 (CIImage) inputImage 属性 并实现了一个 outputImage 方法,该方法 returns 一个 CIImage。我必须提供一个 @objc 覆盖以停止 Xcode 抱怨冲突 Objective-C getter.

当我创建子类滤镜并将其分配给附加到 SKScene 的 SKEffectNode 时,该节点只是绘制一个灰色背景。如果我使用内置过滤器,则 SKEffectNode 工作正常。就我的代码而言,似乎从未调用过我的 outputImage 方法,因为 XCode 永远不会在我放置的任何断点处中断。

我有相同的自定义过滤器,在 Objective-C 中工作正常,Swift 似乎给我带来了一些问题!我的代码如下:

GameScene.swift

import UIKit
import SpriteKit

class StartupScene: SKScene {

override func didMoveToView(view: SKView) {
    anchorPoint = CGPointMake(0.5, 0.5)
    let effectNode = SKEffectNode()
    effectNode.shouldEnableEffects = true
    let filter = OldTimeFilter();
    effectNode.filter = filter

    let backgroundNode = SKSpriteNode(color: UIColor.redColor(), size: frame.size)
    effectNode.addChild(backgroundNode)
    self.addChild(effectNode);

    let labelNode = SKLabelNode(text: "Hello")
    labelNode.fontColor = UIColor.blueColor();
    backgroundNode.addChild(labelNode)
}
}

OldTimeFilter.swift

import Foundation
import CoreImage

class OldTimeFilter:CIFilter
{
var inputImage: CIImage?


@objc(outputImageCI) 
func outputImage() -> CIImage
{
    let time = CFAbsoluteTimeGetCurrent();
    let first = sin(time / 15.0) * 100.0
    let second = sin(time / 2.0) * 25.0

    let v1: [Float] = [Float(first), 1.5]
    let v2: [Float] = [Float(second), 1.5]

    let randVal1 = noise2(UnsafeMutablePointer(v1))
    let randVal2 = noise2(UnsafeMutablePointer(v2))

    let colorControls = CIFilter(name: "CIColorControls")
    colorControls.setValue(0.0, forKey: "InputSaturation")
    colorControls.setValue(randVal2 * 0.2, forKey:"inputBrightness")

    let vignette = CIFilter(name: "CIVignette")
    vignette.setValue(0.2+randVal2, forKey: "inputRadius")
    vignette.setValue(randVal2 * 0.2 + 0.8, forKey: "inputIntensity")


    var transform = CGAffineTransformMakeTranslation(
        CGFloat(0.0), CGFloat(randVal1 * 45.0))

    colorControls.setValue(inputImage, forKey: kCIInputImageKey)
    vignette.setValue(colorControls.outputImage,
        forKey: kCIInputImageKey)
    return vignette.outputImage.imageByApplyingTransform(transform)

}
}

如果我从过滤器中删除@objc(outputImageCI),我会从 Xcode 得到这个错误: "Method outputImage() with Objective-C selector 'outputImage' conflicts with getter for 'outputImage' from superclass 'CIFilter' with the same Objective-C selector"

我是不是漏掉了一些非常明显的东西?

outputImage 是一个计算 属性 而不是方法,所以替换

@objc(outputImageCI) 
func outputImage() -> CIImage

有了这个

override var outputImage:CIImage!