保存sknodes数组

时间:2018-01-27 16:35:24

标签: swift sprite-kit sknode

我有一个功能可以保存场景中的所有节点,还有一个可以将它们添加回来的功能(这些功能在应用程序打开时运行良好)。我遇到的问题是如何保存该数组,以便在应用重新打开时调用它。在此先感谢您的帮助。

为我的节点添加了代码,以便更好地了解我想要完成的内容

let bubble = SKShapeNode(circleOfRadius: self.frame.size.width / 12)
    bubble.position = testBubble.position
    bubble.fillColor = SKColor.black
    bubble.strokeColor = SKColor.black
    bubble.name = "bubble"
    bubble.physicsBody = SKPhysicsBody(circleOfRadius: bubble.frame.height / 2)
    bubble.zPosition = 2

let bubbleLabel = SKLabelNode(text: "Bubble")
    bubbleLabel.fontColor = UIColor.darkGray
    bubbleLabel.fontSize = 10
    bubbleLabel.fontName = "MarkerFelt-Thin"
    bubbleLabel.position.y = bubble.frame.size.width / 2 -bubble.frame.size.height / 1.65
    bubbleLabel.zPosition = 3

    self.addChild(bubble)
    bubble.addChild(bubbleLabel)

@objc func saveAllNodes() {
    nodeArray.removeAll()
    for node in self.children {
        nodeArray.append(node)
    }
}  

@objc func addAllNodes() {
    self.removeAllChildren()
    for node in nodeArray {
        self.addChild(node)
    }
}

2 个答案:

答案 0 :(得分:0)

您可能正在考虑使用CoreData或UserDefaults。当应用程序在您需要的任何地方的viewdidload函数中进入前景或(可能更好)时,让节点在AppDelegate中加载。
您可以在xdatamodel中为您使用NodeArrays中的transformables并将其声明为@NSManaged var [NodeArray]

答案 1 :(得分:0)

请勿打扰CoreDataUserDefaultsSKNodes由于某种原因符合NSCoding,因此请改用KeyedArchiver。当您的应用关闭时,只需保存场景本身,当您的应用打开时,重新加载它。

注意这是针对Swift 3的,不确定Swift 4中有多少Codable发生了变化,但这个想法应该是一样的。

extension SKNode
{
    func getDocumentsDirectory() -> URL 
    {
        let paths = FileManager.default.urls(for: .documentDirectory, in: .userDomainMask)
        return paths[0]
    }


    func save()
    {
        let fullPath = getDocumentsDirectory().appendingPathComponent(name)

        let data = NSKeyedArchiver.archivedData(withRootObject: scene)

        do 
        {
            try data.write(to: fullPath)
        }
        catch 
        {
            print("Couldn't write file")
        }
    }

    static func load(name:String) -> SKNode?
    {

        let fullPath = SKScene.getDocumentsDirectory().appendingPathComponent(name)

        guard let node = NSKeyedUnarchiver.unarchiveObject(withFile: fullPath.absoluteString) as? SKNode 
        else 
        {
            return nil
        }
        return node
    }
}

然后使用它,当您需要保存场景时,只需在场景文件中调用save(),然后加载它就可以调用

guard let scene = SKNode.load("*myscenename*") as? SKScene
else
{
  //error out somehow
}
view.presentScene(scene)

要超越NSCoding的正常功能,您还需要实现编码和解码。这是为你自定义类时添加变量

编码:

func encode(with coder:NSCoder)
{
    coder.encode(variable, forKey:"*variable*")
}

解码:

required init(coder decoder:NSCoder)
{
    super.init(coder:decoder)
    if let variable = decoder.decodeObject(forKey:"*variable*") as? VariableType
    {
        self.variable = variable
    }
}