2017-08-29 5 views
0

Ce code se bloque car secondBody n'est pas associé à un noeud.Crash SpriteKit: comment un corps physique peut-il perdre son association avec SKNode?

func didBegin(_ contact: SKPhysicsContact) { 
    // Set vars to hold bodies 
    var firstBody: SKPhysicsBody 
    var secondBody: SKPhysicsBody 

    // Sort bodies 
    if contact.bodyA.categoryBitMask < contact.bodyB.categoryBitMask { 
     firstBody = contact.bodyA 
     secondBody = contact.bodyB 
    } else { 
     firstBody = contact.bodyB 
     secondBody = contact.bodyA 
    } 

    // Handle different contacts 
    if firstBody.categoryBitMask == BallBitMask && secondBody.categoryBitMask == TileBitMask { 
     didBallTileHit(tile: secondBody.node!) // Code crashes here :(
    } 

    ... 
} 

1) En dehors de la fixation d'un corps physique à nil, ce qui causerait un corps physique pour perdre association avec un nœud SpriteKit?

2) Comment un corps physique peut-il exister même sans noeud en premier lieu?

+0

Je ne sais pas comment ce la cause réelle de votre accident est si je ne vais pas poster une réponse, mais je vais essayer de répondre vos deux questions du mieux que je peux. En ce qui concerne 1), je suppose que l'assignation d'un corps physique différent à votre nœud entraînerait la dissociation du corps physique d'origine. En ce qui concerne 2), la propriété node est faible et facultative (pour éviter un cycle de référence avec le nœud propriétaire, je suppose). Les initialiseurs de SKPhysicsBody ne prennent pas un nœud comme argument; vous passez le corps créé à la propriété 'physicsBody' d'un noeud à la place. Je crois que faire cela à son tour définit la propriété 'node' du corps en conséquence. –

+0

Néanmoins, je suppose que le 'contact' passé à votre méthode (est-ce un délégué de collision de quelque sorte?) Ne contient aucun corps de physique détaché (c'est-à-dire, des corps qui n'appartiennent pas à un nœud); Quel serait le but? –

+0

@NicolasMiari précisément, quel est le point d'un corps détaché? d'où la confusion sur ce qui se passe! Aucune suggestion? – Crashalot

Répondre

1

Un SKSPhysicsBody est un objet en soi et parfaitement capable d'être encore créé pas associé à un SKSpriteNode (bien que l'utilisation peut-être pas de beaucoup :-))

Dans votre didBallTileHit(), avez-vous removeFromParent() un des nœuds? Si c'est le cas, c'est probablement la cause de votre crash dans lequel Sprite-Kit a généré plusieurs collisions entre 2 objets et appelle didBegin() plusieurs fois pour les 2 nœuds. Si vous partez et supprimez un des noeuds du premier appel à didBegin(), il ne sera pas là pour le 2ème et les appels suivants. La façon de le gérer (vous ne pouvez pas obtenir le kit de sprite pour ne PAS appeler didBegin plusieurs fois dans certaines circonstances) est de s'assurer que votre code de contact s'adapte à cela et que la gestion du contrat plusieurs fois ne pose pas de problème (comme ajouter plusieurs fois au score, supprimer plusieurs vies, essayer d'accéder à un nœud ou à un physicsBody qui a été supprimé, etc.).

Pour plus de détails et les solutions possibles, voir cette réponse: https://stackoverflow.com/a/44384390/1430420

+0

cela semble être le coupable! testera et rendra compte, merci beaucoup! – Crashalot

+0

c'était le problème, merci beaucoup! – Crashalot

1

Vous pouvez gérer le contact dans différentes méthodes.

La façon plus facile pour vous est de mettre ceci:

func didBegin(_ contact: SKPhysicsContact) { 

    let bodyA = contact.bodyA 
    let bodyB = contact.bodyB 

    guard let nodeA = bodyA.node as? SKSpriteNode, 
      let nodeB = bodyB.node as? SKSpriteNode, 
      let parentNodeA = nodeA.parent, 
      let parentNodeB = nodeB.parent 
    else {return} 

    //all your stuff 
}