SpriteKit操作,如“Skew”或“Distort”

时间:2017-04-16 23:16:17

标签: swift sprite-kit

是否可以在SpriteKit中为SKSpriteNode创建SKAction,使用Edit-> Transform-> Distort选项生成与“Photoshop”相同的效果?

示例:

Distort image

3 个答案:

答案 0 :(得分:2)

您可以使用1x1变形网格创建倾斜。 iOS10.0 +支持此功能。

此扩展名接收以度为单位的偏斜角,并在给定精灵的锚点周围变形。

Swift 4.2

extension SKWarpGeometryGrid {

    public static var skewPosGridZero:[float2] {
        get {
            return [float2(0.0, 0.0), float2(1.0, 0.0),
                    float2(0.0, 1.0), float2(1.0, 1.0)]
        }
    }

    public static func skewXPosGrid(_ skewX: CGFloat, node:SKSpriteNode? = nil) -> [float2] {

        let anchorY:Float = Float(node?.anchorPoint.y ?? 0.5)  
        var skewPosGrid = skewPosGridZero
        let offsetX = Float(tan(skewX.degToRad()) * (node == nil ? 1.0 : (node!.size.height/node!.size.width)) )
        skewPosGrid[2][0] += offsetX * (1.0 - anchorY)
        skewPosGrid[3][0] += offsetX * (1.0 - anchorY)
        skewPosGrid[0][0] -= offsetX * anchorY
        skewPosGrid[1][0] -= offsetX * anchorY

        return skewPosGrid

    }

    public static func skewYPosGrid(_ skewY: CGFloat, node:SKSpriteNode? = nil) -> [float2] {

        let anchorX:Float = Float(node?.anchorPoint.x ?? 0.5)  
        var skewPosGrid = skewPosGridZero
        let offsetY = Float(tan(skewY.degToRad()) * (node == nil ? 1.0 : (node!.size.width/node!.size.height)) )
        skewPosGrid[1][1] += offsetY * (1.0 - anchorX)
        skewPosGrid[3][1] += offsetY * (1.0 - anchorX)
        skewPosGrid[0][1] -= offsetY * anchorX
        skewPosGrid[2][1] -= offsetY * anchorX

        return skewPosGrid

    }

    public static func skewX(_ angle: CGFloat, node:SKSpriteNode? = nil) -> SKWarpGeometryGrid {

        return SKWarpGeometryGrid(columns: 1, rows: 1, sourcePositions: skewPosGridZero, destinationPositions: skewXPosGrid(angle, node:node))

    }
    public static func skewY(_ angle: CGFloat, node:SKSpriteNode? = nil) -> SKWarpGeometryGrid {

        return SKWarpGeometryGrid(columns: 1, rows: 1, sourcePositions: skewPosGridZero, destinationPositions: skewYPosGrid(angle, node:node))

    }

    public static func skewZero() -> SKWarpGeometryGrid {
        return SKWarpGeometryGrid(columns: 1, rows: 1)
    }

}

动画示例:

    let spriteNode = SKSpriteNode(imageNamed: "tex")
    spriteNode.anchorPoint = CGPoint(x:0.25, y:1.0)
    let skewA = SKWarpGeometryGrid.skewX(-45.0, node: spriteNode)
    let skewB = SKWarpGeometryGrid.skewX(45.0, node: spriteNode)
    spriteNode.warpGeometry = skewB
    if let skewActionA = SKAction.warp(to: skewA, duration: 3.0),
        let skewActionB = SKAction.warp(to: skewB, duration: 3.0){
        // Individual easing
        skewActionA.timingMode = .easeInEaseOut
        skewActionB.timingMode = .easeInEaseOut
        spriteNode.run(SKAction.repeatForever(SKAction.sequence([skewActionA,skewActionB])))
    }

答案 1 :(得分:1)

可用的SKAction列表位于:https://developer.apple.com/reference/spritekit/skaction

没有人能够完全按照你的描述去做。相反,您可以从像Photoshop这样的照片编辑工具导出多个精灵图像,并使用像class func animate(with: [SKTexture], timePerFrame: TimeInterval)这样的动画操作。

这是一项更多的工作,但应该达到预期的效果。

答案 2 :(得分:1)

我解决了这个实现:

Swift 3

extension SKSpriteNode {

    func addSkew(value: CGFloat = -1){

        var effectNode = SKEffectNode()
        effectNode.shouldRasterize = true
        effectNode.shouldEnableEffects = true
        effectNode.addChild(SKSpriteNode(texture: texture))
        effectNode.zPosition = 1
        let transform      = CGAffineTransform(a:  1    , b:  0,
                                               c:  value , d:  1,
                                               tx: 0    , ty: 0)
        let transformFilter = CIFilter(name: "CIAffineTransform")!
        transformFilter.setValue(transform, forKey: "inputTransform")
        effectNode.filter = transformFilter
        addChild(effectNode)
        texture = nil

    }

}