Non è possibile ottenere il comportamento desiderato perché non è stata impostata correttamente la categoria, il contatto e le maschere di bit di collisione. Ecco un esempio di come è possibile impostare questo lavoro:
greenBall.physicsBody?.categoryBitMask = GreenBallCategory //Category is GreenBall
greenBall.physicsBody?.contactTestBitMask = RedBarCategory | WallCategory //Contact will be detected when GreenBall make a contact with RedBar or a Wall (assuming that redBar's masks are already properly set)
greenBall.physicsBody?.collisionBitMask = GreenBallCategory | RedBallCategory | WallCategory //Collision will occur when GreenBall hits GreenBall, RedBall or hits a Wall
redBall.physicsBody?.categoryBitMask = RedBallCategory //Category is RedBall
redBall.physicsBody?.contactTestBitMask = GreenBarCategory | GreenBallCategory | WallCategory //Contact will be detected when RedBall make a contact with GreenBar , GreenBall or a Wall
redBall.physicsBody?.collisionBitMask = RedBallCategory | GreenBallCategory | WallCategory //Collision will occur when RedBall meets RedBall, GreenBall or hits a Wall
let borderBody = SKPhysicsBody(edgeLoopFromRect: self.frame)
self.physicsBody = borderBody
self.physicsBody?.friction = 0
borderBody.contactTestBitMask = RedBallCategory | GreenBallCategory //Contact will be detected when red or green ball hit the wall
borderBody.categoryBitMask = WallCategory
borderBody.collisionBitMask = RedBallCategory | GreenBallCategory // Collisions between RedBall GreenBall and a Wall will be detected
ti consiglierei di leggere documenti su categoryBitMask che è una maschera che definisce le categorie di un corpo di fisica appartiene a:
Ogni il corpo della fisica in una scena può essere assegnato a un massimo di 32 diverse categorie , ciascuna corrispondente ad un bit nella maschera bit. Tu definisci i valori della maschera usati nel tuo gioco. In concomitanza con le proprietà collisionBitMask e contactTestBitMask , è possibile definire quali corpi fisici di interagiscono tra loro e quando viene notificato al gioco di queste interazioni.
contactTestBitMask - Una maschera che definisce quali categorie di corpi causano notifiche di intersezione con un corpo fisico corrente.
Quando due corpi condividono lo stesso spazio, maschera categoria di ciascun organismo è testati contro maschera contatti dell'altro corpo eseguendo una logica AND. Se uno dei due risultati risulta in un valore diverso da zero, viene creato un oggetto SKPhysicsContact e inviato al delegato del mondo fisico . Per ottenere prestazioni ottimali, i bit solo impostati nei contatti maschera per interazioni siete interessati a
collisionBitmask -. Una maschera che definisce le categorie di enti di fisica possono collidere con questo corpo fisico.
Quando due corpi fisici si contattano, è possibile che si verifichi una collisione. La maschera di collisione di questo corpo viene confrontata con la maschera di altro corpo della categoria eseguendo un'operazione AND logica. Se il risultato è un valore diverso da zero , questo corpo è interessato dalla collisione. Ogni corpo indipendente sceglie se vuole essere influenzato dall'altro corpo. Per esempio , è possibile utilizzarlo per evitare calcoli di collisione che farebbero modifiche trascurabili alla velocità di un corpo.
Quindi, fondamentalmente, per impostare tutti questi, si dovrebbe chiedere il vostro sé qualcosa di simile:
Va bene, ho una palla verde, e una palla rossa, e gli oggetti a muro sulla scena. Tra quali corpi voglio che si verifichino collisioni o quando voglio registrare i contatti? Voglio che una palla verde e una rossa si scontrino tra loro e scontrino contro i muri. Non è un problema. Io innanzitutto impostare categorie correttamente, e poi mi metterò bit maschere di collisione in questo modo:
greenBall.collisionBitMask = GreenBallCategory | RedBallCategory | WallCategory; //greenBall will collide with greenBall, redBall and a wall
redBall.collisionBitMask = GreenBallCategory | RedBallCategory | WallCategory
wall.collisionBitMask = GreenBall | RedBall
Ora, voglio rilevare quando si verificano alcuni contatti (in didBeginContact
: metodo) ... Ma non fare vuoi essere avvisato di tutti i possibili contatti, ma piuttosto di essere informato solo sui contatti tra le sfere (i contatti tra le palle e un muro saranno ignorati). Quindi, consente di impostare contactTestBitMasks
per raggiungere questo obiettivo:
greenBall.contactTestBitMask = GreenBallCategory | RedBallCategory;
redBall.contactTestBitMask = GreenBallCategory | RedBallCategory;
E questo è tutto. L'importante è che quando non si utilizza il rilevamento dei contatti, non si deve impostare contactTestBitMask
. Questo è dovuto a motivi di prestazioni. Se non è necessario il rilevamento delle collisioni e si è interessati solo a rilevare i contatti, è possibile impostare collisionBitMask = 0
.
Importante:
Assicurarsi di aver impostato delegato contatto del mondo della fisica, al fine di utilizzare didBeginContact
e didEndContact
metodi:
self.physicsWorld.contactDelegate = self; //where self is a current scene
Spero che questo aiuti un po '.
Incredibile risposta, grazie mille per aver dedicato del tempo a scrivere tutto questo. Funziona perfettamente. La parte "chiedi a te stesso" ha sicuramente chiarito su cosa mi ero confuso. Grazie mille, così tanto! – Noowoo
Che dire se ne hai più di 32? – cnzac
@Abcdefg Come si può rilevare la fine della collisione nella funzione didEnd? – Marin