Swift/SpriteKit-有没有办法共享/缓存SKReferenceNodes?

Swift/SpriteKit-有没有办法共享/缓存SKReferenceNodes?,swift,caching,sprite-kit,preloading,skreferencenode,Swift,Caching,Sprite Kit,Preloading,Skreferencenode,有没有一种方法可以使用Swift在SpriteKit中池/缓存SKReferenceNodes 我正在使用xCodes可视级别编辑器创建一个游戏。我正在使用可视级别编辑器创建不同的.sks文件,而不是在需要时调用代码。我在代码中调用它们,因为我使用它们来创建随机级别或障碍物,所以我不需要一次将它们全部添加到场景中 目前我正在这样做 let room = allRooms[0] room.position = addChild(room) // causes error/crash -&g

有没有一种方法可以使用Swift在SpriteKit中池/缓存SKReferenceNodes

我正在使用xCodes可视级别编辑器创建一个游戏。我正在使用可视级别编辑器创建不同的.sks文件,而不是在需要时调用代码。我在代码中调用它们,因为我使用它们来创建随机级别或障碍物,所以我不需要一次将它们全部添加到场景中

目前我正在这样做

 let room = allRooms[0]
 room.position = 
 addChild(room) // causes error/crash -> node already has parent
我为SKReferenceNodes创建了一个converse init方法,用URL初始化它们。我这样做是因为有某种bug直接通过文件名()调用SKReferenceNodes。 使用这样的扩展可以使代码更简洁

 extension SKReferenceNode {

convenience init(roomName: String) {
    let path: String
    if let validPath = NSBundle.mainBundle().pathForResource(roomName, ofType: "sks") {
        path = validPath
    } else {
        path = NSBundle.mainBundle().pathForResource("RoomTemplate", ofType: "sks")! // use empty roomTemplate as backup so force unwrap
    }

    self.init(URL: NSURL(fileURLWithPath: path))
}
}

在我的场景中,我可以像这样创建和添加它们(大约每10秒)

这一切正常,但我得到一些滞后/口吃时,创建这些。所以我用GCD来减少口吃。它工作得很好,但我想知道是否可以先预加载所有的.sks文件

我尝试使用数组来实现这一点,但我遇到了崩溃,而且似乎不起作用(我还收到一条消息,已经在添加具有父节点的节点)

在应用程序发布时,我试图像这样预加载它们

 let allRooms = [SKReferenceNode]()

 for i in 0...3 {
     let room = SKReferenceNode(roomName: "Room\(i)")
     allRooms.append(room)
 }
而不是在我需要的时候使用数组。然而,这不起作用,当我试图使用这样的代码时,我会崩溃

 let room = allRooms[0]
 room.position = 
 addChild(room) // causes error/crash -> node already has parent

有人做过类似的事情吗?是否有其他方法可以共享/缓存这些引用节点?。我在这里遗漏了什么吗?

说到
SKReferenceNode
预加载,我认为应该遵循的策略是加载对象,找到它们的类型,并使用Sprite工具包中提供的官方预加载方法

为了避免这种错误,您应该创建单独的节点实例

尝试这样做:

let room = allRooms[0]
room.position = ...
room.removeFromParent()
addChild(room)

我才明白,我只是个白痴

像我希望的那样使用数组是可以的,导致崩溃的问题如下

当游戏场景第一次加载时,我添加了3个房间,但在使用阵列进行测试时,我一直添加相同的房间

let room = allRooms[0]
而不是使用随机化器。 这显然意味着我多次添加同一个实例,因此导致崩溃

使用随机化器,这不会在同一个房间重复,这不会发生

此外,当我不再需要房间时,我会确保将其从场景中移除。我在rooms中有一个节点(roomRemover),它触发一个方法,一旦它与玩家接触,就可以移除/创建一个新的房间。 这将是DidBeginContact中的代码

 guard let roomToRemove = secondBody?.node.parent?.parent?.parent?.parent else { return }
 // secondBody is the roomRemover node which is a child of the SKReferenceNode. 
 // If I want to remove the whole SKReferenceNode I need to add .parent 4 times. 
 // Not exactly sure why 4 times but it works

 for room in allRooms {
    if room == roomToRemove {
        room.removeFromParent()
    }
 }
 loadRandomRoom()

希望这有助于尝试做同样事情的人。

嘿,非常感谢您的回复。我刚刚解决了我的问题,我现在发布了一个答案。再次感谢您的努力。欢迎您,也感谢您分享您的经验:)再次非常感谢您的帮助。