简体   繁体   中英

SKEffectNode will not use custom CIFilter in Swift

I'm attempting to subclass CIFilter for use in a SpriteKit game, as described in the iOS Games by Tutorials book. I have created my subclass inheriting from CIFilter, which has a (CIImage) inputImage property and implements an outputImage method which returns a CIImage. I had to provide an @objc override in order to stop Xcode complaining about a conflicting Objective-C getter.

When I create and assign my subclassed filter to an SKEffectNode attached to an SKScene, the node simply draws a gray background. If I use a built-in filter the SKEffectNode works just fine. As far as my code is concerned, it doesn't appear that my outputImage method is ever called, as XCode never breaks on any breakpoint I place within.

I have the same custom filter working fine in Objective-C, Swift just seems to be giving me some issues! My code is as follows:

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)

}
}

If I remove @objc(outputImageCI) from the filter I get this error from Xcode: "Method outputImage() with Objective-C selector 'outputImage' conflicts with getter for 'outputImage' from superclass 'CIFilter' with the same Objective-C selector"

Am I missing something incredibly obvious?

outputImage is a computed property not a method, so replace

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

with this

override var outputImage:CIImage!

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM