如何将SKSpriteNode放在CAShapeLayer前面?

时间:2017-08-04 13:59:40

标签: swift sprite-kit cashapelayer

我想在CAShapeLayer前面显示一个SKSpriteNode,这是我正在使用的代码:

import SpriteKit
import GameplayKit
import UIKit

class GameScene: SKScene {

    let progressLayer = CAShapeLayer()

    override func didMove(to view: SKView) {

        let circle = UIView(frame: CGRect(x: 0, y: 0, width: self.size.width, height: self.size.height))
        view.addSubview(circle)
        view.sendSubview(toBack: circle)

        progressLayer.frame = view.bounds
        progressLayer.path = progressPath.cgPath

        progressLayer.fillColor = UIColor.clear.cgColor
        progressLayer.strokeColor = UIColor.green.cgColor
        progressLayer.lineWidth = 20.0

        let animation2 = CABasicAnimation(keyPath: "strokeEnd")
        animation2.fromValue = 0.0
        animation2.toValue = 1.0
        animation2.duration = 1
        animation2.timingFunction = CAMediaTimingFunction(name: kCAMediaTimingFunctionEaseOut)

        progressLayer.add(animation2, forKey: "drawLineAnimation")

        circle.layer.addSublayer(progressLayer)

        var popup = SKSpriteNode(imageNamed: "popupWorking.png")
        popup.anchorPoint = CGPoint(x: 0.5, y: 0.5)
        popup.position = CGPoint(x: self.size.width/2, y: self.size.height/2)
        popup.size = CGSize(width: 400, height: 200)
        popup.zPosition = 10
        self.addChild(popup)
    }
}

但是当我运行代码时,CAShapeLayer出现在SKSpriteNode的前面,如何让SKSpriteNode出现在CAShapeLayer的前面?

2 个答案:

答案 0 :(得分:2)

您需要在视图控制器级别更改视图层次结构。默认情况下,视图控制器的视图为SKView。如果您想在UIView后面放置不同的SKView,则需要调整视图层次结构。

将视图控制器的视图修改为UIView而不是SKView。然后,将形状图层的视图作为子视图添加到此主视图中。之后,将您的SKView添加为主视图的子视图。

您的新视图层次结构应如下所示:

View Controller
    – view (UIView)
        - circle view (UIView with your CAShapeLayer as a sublayer)
        - spritekit view (SKView)

虽然可以通过这种方式合并UIKitSpriteKit,但可能更容易保持SpriteKit世界并使用SKSpriteNode s重新创建圆圈动画而不是CAShapeLayer

答案 1 :(得分:0)

这是一个游乐场,展示了一种方法。我按照@nathan的建议。

使用SKShapeNode绘制黄线。红色阴影需要在它后面动画,因此使用CAShapeLayer。 (注意:我需要混合两者,因为动画阴影路径在纯Sprite中要复杂得多)

import SpriteKit
import PlaygroundSupport

private func invert(_ path: CGMutablePath)  -> CGPath {
    var rotation = CGAffineTransform(scaleX: 1.0, y: -1.0);
    return path.copy(using: &rotation)!;
}

let bounds = CGRect(x: 0, y: 0, width: 400, height: 200)
let uiview = UIView(frame: bounds)
let pathview = UIView(frame: bounds)
let skview = SKView(frame: bounds)

PlaygroundPage.current.liveView = uiview


// Define the path
let path: CGMutablePath = CGMutablePath();
path.move(to: CGPoint(x:0, y:0))
path.addLine(to: CGPoint(x:200, y:100))


// Use CAShapeLayer to draw the red line
var pathLayer: CAShapeLayer = CAShapeLayer()
pathLayer.position = CGPoint(x: uiview.bounds.minX, y: uiview.bounds.minY + 200)
pathLayer.path = invert(path)
pathLayer.strokeColor = UIColor.red.cgColor
pathLayer.fillColor = nil
pathLayer.lineWidth = 10.0
pathLayer.lineJoin = kCALineJoinBevel
pathLayer.lineCap = kCALineCapRound
pathLayer.zPosition = 3;
let strokeAnimation = CABasicAnimation(keyPath: "strokeAnimation")
strokeAnimation.duration = 2;
strokeAnimation.fromValue = 0;
pathview.layer.addSublayer(pathLayer);
pathLayer.add(strokeAnimation, forKey: "strokePath");

uiview.addSubview(pathview)

//Use SKShapeNode to draw the yellow line
let pathShape: SKShapeNode = SKShapeNode(path: path);
pathShape.strokeColor = .white;
pathShape.lineWidth = 2.0;
pathShape.zPosition = 20;

// Create SK Scene
let scene = SKScene(size: CGSize(width: 400, height: 200))
scene.scaleMode = SKSceneScaleMode.aspectFill
scene.size = skview.bounds.size
scene.addChild(pathShape);
scene.backgroundColor = UIColor.clear;
skview.backgroundColor = UIColor.clear


skview.presentScene(scene);
uiview.insertSubview(skview, aboveSubview: pathview)