Добавьте не размытый SKNode поверх размытого вида - PullRequest
0 голосов
/ 10 июля 2019

Я пытаюсь размыть свой SKScene и все содержащиеся в нем SKNodes, а затем добавить сверху SKShapeNode, который не должен быть размытым.

Это мой код:

import SpriteKit
import GameplayKit

class GameScene: SKScene {

private var label : SKLabelNode?
private var spinnyNode : SKShapeNode?
private var rectangle : SKShapeNode?
private var background : SKSpriteNode?
// This node should not be blurred
private var rectangle1 : SKShapeNode?

override func didMove(to view: SKView) {

    self.label = self.childNode(withName: "//helloLabel") as? SKLabelNode
    if let label = self.label {
        label.alpha = 0.0
        label.run(SKAction.fadeIn(withDuration: 2.0))
    }

    let w = (self.size.width + self.size.height) * 0.05

    // Node that will be a child of the scene and that should be blurred
    self.rectangle = SKShapeNode.init(rectOf: CGSize.init(width: w*5, height: w*5), cornerRadius: w * 0.3)
    if let rectangle = self.rectangle
    {
        rectangle.fillColor = UIColor.red
        addChild(rectangle)
    }

    // Here I create a subview with a blur effect
    let blurEffect = UIBlurEffect(style: UIBlurEffect.Style.light)
    let blurEffectView = UIVisualEffectView(effect: blurEffect)
    blurEffectView.frame = self.view!.bounds
    blurEffectView.autoresizingMask = [.flexibleWidth, .flexibleHeight]
    self.view!.addSubview(blurEffectView)

    // Now I want to create a texture by capturing an image of my self.view and transforming the image to SKTexture
    let textureImage = image(with: self.view!)
    let texture = SKTexture(image: textureImage!)

    // I create a node that will have a blurred texture
    self.background = SKSpriteNode.init(texture: texture)
    if let background = self.background
    {
        addChild(background)
    }

    // Now I create a node that should not be blurred, adding it to the blurred node
    self.rectangle1 = SKShapeNode.init(rectOf: CGSize.init(width: w*3, height: w*3), cornerRadius: w * 0.3)
    if let rectangle1 = self.rectangle1
    {
        rectangle1.fillColor = UIColor.blue
        rectangle1.zPosition = 10
        background!.addChild(rectangle1)

        // Removing the effect makes everything non-blurred.
        // Not removing the effect blurs everything
        blurEffectView.removeFromSuperview()
    }
}

Это для создания изображения из вида

func image(with view: UIView) -> UIImage?
{
    UIGraphicsBeginImageContextWithOptions(view.bounds.size, view.isOpaque, 0.0)
    defer { UIGraphicsEndImageContext() }
    if let context = UIGraphicsGetCurrentContext() {
        view.layer.render(in: context)
        let image = UIGraphicsGetImageFromCurrentImageContext()
        return image
    }
    return nil
}

}

Мой код не работает. Согласно приведенному выше объяснению, оно либо стирает все, либо все не размыто.

На самом деле похоже, что мой фон не правильно инициализирован. Я вижу его как черный прямоугольник размером меньше моего self.view. Нет захваченного размытого изображения внутри.

Может кто-нибудь помочь мне, пожалуйста?

Большое спасибо!

EDIT:

В конечном итоге это сработало:

import SpriteKit
import GameplayKit

class GameScene: SKScene {

private var label : SKLabelNode!
private var rectangle : SKShapeNode!
private var container : SKSpriteNode!
private var rectangle1 : SKShapeNode!
private var button : SKSpriteNode!
private var effectNode : SKEffectNode!
private var blurNode : SKShapeNode!

override func didMove(to view: SKView)
{
    effectNode = SKEffectNode()
    let blurFilter = CIFilter(name: "CIGaussianBlur", parameters: ["inputRadius": 20])
    effectNode.filter = blurFilter
    effectNode.zPosition = 500
    addChild(effectNode)

    blurNode = SKShapeNode(rect: self.frame)
    blurNode.fillColor = .white
    blurNode.isHidden = true
    effectNode.addChild(blurNode)


    self.container = SKSpriteNode()
    //self.container.position = CGPoint(x: frame.width/2, y: frame.height/2)
    self.container.size = CGSize(width: frame.width, height: frame.height)
    self.container.color = UIColor(red: 0/255, green: 100/255, blue: 0/255, alpha: 1)
    addChild(container)


    self.label = SKLabelNode(text: "HELLO WORLD")
    self.label.fontName = "Noteworthy-Bold"
    self.label.fontSize = 100
    self.label.alpha = 1.0
    self.label.color = .red
    self.label.zPosition = 2
    self.label.position = self.convert(CGPoint(x: 5, y: 400),to: container)
    self.container.addChild(self.label)


    self.rectangle = SKShapeNode.init(rectOf: CGSize.init(width: 500, height: 500),
                                      cornerRadius: 30)
    self.rectangle.fillColor = UIColor.green
    self.rectangle.strokeColor = .clear
    self.rectangle.position = self.convert(self.rectangle.position, to: container)
    self.container.addChild(self.rectangle)



    self.button = SKSpriteNode(color: .blue, size: CGSize(width: 300, height: 100))
    self.button.position = self.convert(CGPoint(x: 0, y: -400), to: container)
    self.button.zPosition = 2
    self.button.name = "button"
    self.container.addChild(self.button)

}

override func touchesEnded(_ touches: Set, with event: UIEvent?)
{
    let touch = touches.first
    let positionInScene = touch!.location(in: self)
    let allNodes = nodes(at: positionInScene)
    for node in allNodes
    {
        let nodePositionConverted = self.convert(node.position, from: node)
        let nodeFrameConverted = CGRect(origin: CGPoint(x:nodePositionConverted.x-node.frame.maxX,
                                                        y:nodePositionConverted.y-node.frame.maxY),
                                        size:node.frame.size)
        if nodeFrameConverted.contains(positionInScene)
        {
            if(node == button)
            {
                addMenu()
            }
            else if(node == rectangle1)
            {
                hideMenu()
            }
        }
    }
}


func addMenu()
{
    print("POINT A")
    blurNode.isHidden = false
    let fillTexture = self.view?.texture(from: container, crop: blurNode.frame)
    print("POINT B")
    blurNode.fillTexture = fillTexture

    self.rectangle1 = SKShapeNode.init(rectOf: CGSize.init(width: 300, height: 300), cornerRadius: 30)
    self.rectangle1.fillColor = UIColor.blue
    self.rectangle1.zPosition = 600
    addChild(rectangle1)
}


func hideMenu()
{
    blurNode.isHidden = true
    blurNode.fillTexture = nil
    rectangle1.removeFromParent()
}
}
...