SpriteKit: détecter le chevauchement complet des noeuds

J'ai deux SKShapeNodes – un avec un SKPhysicsBody basé sur les bords, un basé sur le volume – et je veux détecter leur intersection sans collision. Cela fonctionne bien, avec les methods de contact SKPhysicsContactDelegate qui sont appelées lorsque l'on passe sur une autre, mais mon problème est que didEndContact est appelé lorsque les arêtes ne se croisent plus, même lorsqu'un corps est complètement contenu dans l'autre. Quelle est la meilleure façon de déterminer le vrai contact ou le chevauchement, pas seulement l'intersection des arêtes? J'ai essayé usesPreciseCollisionDetection , en vain.

 CGPoint locObj1 = [sprite1 locationInNode:self]; CGPoint locObj2 = [sprite2 locationInNode:self]; if([sprite1 containsPoint: locObj2]) return; if([sprite2 containsPoint: locObj1]) return; 

Ajoutez ceci au début de didBeginContact et didEndContact. Cela vérifie si l'un des nœuds contient l'autre nœud. Si c'est le cas, il ne fait rien qui soulagera votre problème de didBeginContact et didEndContact étant sans appel. Je ne suis pas sur mon mac donc vous devrez peut-être jouer avec la syntaxe un peu. J'espère que cela vous envoie dans la bonne direction.

Comme suggéré par Meisenman , il semble que la meilleure façon d'y parvenir est d'utiliser la méthode containsPoint pour déterminer le chevauchement réel des nœuds. Les docs déclarent que ceci "renvoie une valeur booleanne qui indique si un point se trouve à l'intérieur de la boîte englobante du nœud", mais dans mon expérimentation, il semble que cela fonctionne également pour les forms concaves à base de bords.

Donc, si je veux détecter quand deux objects ne se chevauchent plus, il est logique de faire une vérification de didEndContact dans didEndContact – mais il s'avère que didEndContact est appelé quand chaque arête n'est plus recoupée, même si un autre arête de la même forme recoupe même object. Par exemple, une balle sortant d'un rectangle par son coin donnera deux events didEndContact . Par conséquent, il est nécessaire de conserver un nombre absolu d'events de contact (la différence entre le début et la fin), et de tester uniquement le confinement lorsque ce count est égal à zéro.

Ma solution, dans Swift:

 var _contactCount = 0 func didBeginContact(contact: SKPhysicsContact!) { if ((contact.bodyA.categoryBitMask | contact.bodyB.categoryBitMask) == (CATEGORY_ONE | CATEGORY_TWO)) { if (_contactCount == 0) { // Contact is actually beginning } _contactCount += 1 } } func didEndContact(contact: SKPhysicsContact!) { if ((contact.bodyA.categoryBitMask | contact.bodyB.categoryBitMask) == (CATEGORY_ONE | CATEGORY_TWO)) { _contactCount -= 1 let overlap = contact.bodyA.node.containsPoint(contact.bodyB.node.position) || contact.bodyB.node.containsPoint(contact.bodyA.node.position) if (!overlap && _contactCount == 0) { // Contact is actually ending } } } 

Ce sont mes pensées sur l'exemple #meisenman pour swift 3. Au lieu de la détection de collision à travers les masques, disons que nous voulions savoir si un nœud est à l'intérieur d'un nœud. Avec #meisenman, l'location du nœud est utilisé pour chacun.

Image Exemple de CGPoint de deux nœuds différents.

Cette image suivante est ce que nous faisons réellement ce que je veux faire.

Exemple d'image de deux CGPoint l'un dans l'autre.

Le code #meisenman utilise ne nécessite pas SKPhysics. Voici le code dans Swift 3.0

 let Object_1: CGPoint! = Sprite_Object_1.position //this obtains the location of the sprite node, through CGPoint. if Object_Sprite_2.contains(Object_1){ print("Then it is true, object 2 is within the location of object 1") } 

Les seules limitations que j'ai trouvées sont que si le centre de ces nœuds n'est pas dans le corps du nœud désiré, alors cette instruction if ne sera pas vraie. Cela n'a pas été testé en définissant la définition du corps du noeud (masque).

Ce que j'aime, c'est d'avoir la possibilité d'utiliser cette instruction if à travers différentes fonctions ou surpasser les fonctions, cela ne se limite pas seulement aux «a commencé» ou aux «touches déplacées».
Exemple d'image de deux CGPoint l'un dans l'autre, avec des limitations possibles.