SpriteKit将一个节点的子节点添加到另一个节点

时间:2014-11-18 18:23:05

标签: swift sprite-kit

在我的精灵工具包项目中,我有一个场景.sks文件,其中包含地面物理实体和背景图形。将从此文件加载场景。它还包含一个名为container的空节点。我有每个级别的另一个.sks文件,其中包含块和敌人。当我的场景初始化时,我从我的一个级别.sks文件中加载一个级别(将SKScene转换为SKNode)并添加到空的"容器中#34;节点。我使用这段代码:

import SpriteKit

extension SKNode {
    class func unarchiveFromFile(file : NSString) -> SKNode? {
        if let path = NSBundle.mainBundle().pathForResource(file, ofType: "sks") {
            var sceneData = NSData(contentsOfFile: path, options: .DataReadingMappedIfSafe, error: nil)!
            var archiver = NSKeyedUnarchiver(forReadingWithData: sceneData)

            archiver.setClass(SKNode.classForKeyedUnarchiver(), forClassName: "SKScene")
            let scene = archiver.decodeObjectForKey(NSKeyedArchiveRootObjectKey) as SKNode
            archiver.finishDecoding()
            return scene
        } else {
            return nil
        }
    }
}

class GameScene: SKScene {
    required init?(coder aDecoder: NSCoder) {
        super.init(coder: aDecoder)

        self.childNodeWithName("//container")?.addChild(SKNode.unarchiveFromFile("level1")!)
    }

    override class func unarchiveFromFile(file : NSString) -> SKNode? {
        if let path = NSBundle.mainBundle().pathForResource(file, ofType: "sks") {
            var sceneData = NSData(contentsOfFile: path, options: .DataReadingMappedIfSafe, error: nil)!
            var archiver = NSKeyedUnarchiver(forReadingWithData: sceneData)

            archiver.setClass(self.classForKeyedUnarchiver(), forClassName: "SKScene")
            let scene = archiver.decodeObjectForKey(NSKeyedArchiveRootObjectKey) as GameScene
            archiver.finishDecoding()
            return scene
        } else {
            return nil
        }
    }
}

但是,这意味着节点层次结构中有一个空的未使用节点:

Scene
-background
-ground
-container
--level scene(cast to SKNode) <- empty node here
---block
---enemy

所以我的问题是:如何将一个节点的孩子添加到另一个节点? - 我不能直接设置子属性(不可分配)
- 我无法替换容器节点,因为我松开了它的所有属性

2 个答案:

答案 0 :(得分:1)

只需迭代children数组 - 您需要从AnyObject转换回SKNode以将节点添加到新父节点:

for node in oldParentNode.children {
    node.removeFromParent()
    newParentNode.addChild(node as AnyObject)
}

答案 1 :(得分:0)

这应该是诀窍(未经测试),只需逐个添加:

for (CCNode* node in [oneNode.children copy]) 
{
    [node removeFromParent]; 
    [anotherNode addChild:node];
}

需要副本以避免在枚举子数组时改变它。或者,您也可以使用reverseObjectEnumerator。必须删除节点,因此addChild:不会抱怨已经拥有父节点的节点。