2016-07-04 9 views
1

Existe-t-il un moyen de mettre en pool/mettre en cache SKReferenceNodes dans SpriteKit en utilisant Swift?Swift/SpriteKit - Un moyen de mettre en pool/cache SKReferenceNodes?

Je crée un jeu en utilisant l'éditeur de niveau visuel xCodes. Je crée différents fichiers .sks avec l'éditeur de niveau visuel que je suis en train d'appeler du code quand j'en ai besoin. Je les appelle en code parce que je les utilise pour créer des niveaux ou des obstacles aléatoires, donc je n'ai pas besoin que tout soit ajouté à la scène en même temps.

En ce moment je fais comme ça

Je crée une méthode init pour convaincre SKReferenceNodes de les initialiser avec des URL. Je fais ceci parce qu'il y a une sorte de bogue appelant SKReferenceNodes par le nom de fichier directement (https://forums.developer.apple.com/thread/44090). L'utilisation d'une telle extension rend le code un peu plus propre.

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)) 
} 

}

et que dans mes scènes que je peux les créer et les ajouter comme si (environ toutes les 10 secondes)

let room = SKReferenceNode(roomName: "Room1") // will cause lag without GCD 
room.position = ... 
addChild(room) 

Cela fonctionne ok mais je reçois un certain retard/bégayer lors de la création de ceux-ci Donc, j'utilise GCD pour réduire cela à pratiquement aucun bégaiement. Cela fonctionne bien mais je me demande si je peux précharger tous les fichiers .sks en premier.

J'ai essayé d'utiliser des tableaux pour cela, mais je reçois des plantages et cela ne semble pas fonctionner (je reçois également un message ajoutant déjà un nœud qui a un parent).

je tentais de les précharger comme tant à l'application lancement

let allRooms = [SKReferenceNode]() 

for i in 0...3 { 
    let room = SKReferenceNode(roomName: "Room\(i)") 
    allRooms.append(room) 
} 

et que d'utiliser le tableau quand j'ai besoin aussi. Cela ne fonctionne pas cependant et je reçois un plantage en essayant d'utiliser le code comme ceci

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

Quelqu'un at-il fait quelque chose de similaire? Existe-t-il un autre moyen de mettre en pool/mettre en cache ces nœuds de référence? Est-ce que j'ai râté quelque chose?

Répondre

1

j'ai pensé juste, j'étais juste un idiot.

L'utilisation de tableaux comme je le voulais est très bien, le problème que j'avais qui a causé le crash était le suivant.

Lorsque la scène du jeu premier chargement J'ajoute 3 chambres, mais lors des tests avec les tableaux que je gardé en ajoutant la même pièce

let room = allRooms[0] 

au lieu d'utiliser un randomiser. Cela signifiait évidemment que j'ajoutais la même instance plusieurs fois, d'où le crash.

Avec un randomisateur, cela ne répète pas la même pièce, cela n'arrive pas.

En outre, je m'assure de retirer la pièce de la scène lorsque je n'en ai plus besoin. J'ai un nœud dans les chambres (roomRemover) qui déclenche une méthode pour supprimer/créer une nouvelle pièce une fois qu'elle entre en contact avec le joueur. Ce serait le code dans 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() 

Espérons que cela aide quelqu'un qui essaie de faire la même chose.

1

Parlant de la pré-charge SKReferenceNode, je pense que la politique à suivre est de charger votre objet, trouver quel genre ils sont et utiliser les méthodes de préchargement officielles disponibles dans Sprite-Kit:

Pour éviter ce genre d'erreur, vous devez créer des instances distinctes des noeuds.

Essayez de le faire:

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

Salut, merci beaucoup pour votre réponse. Je viens de comprendre mes problèmes, je viens de poster une réponse maintenant. Merci encore pour vos efforts. – crashoverride777

+0

Vous accueillir, merci aussi de partager votre expérience :) –

+0

Merci beaucoup pour votre aide. – crashoverride777