ios swift sprite-kit interop skphysicscontact

ios - didBeginContact pasó el PKPhyicsObject



swift sprite-kit (1)

Me sale el mismo error con este código simple:

extension SKPhysicsContact { func bodiesMatchingCategory(mask: UInt32) -> [SKPhysicsBody] { let bodies = [bodyA, bodyB] return bodies.filter { ($0.categoryBitMask & mask) != 0 } } } let contact = SKPhysicsContact() let body = contact.bodiesMatchingCategory(0)

El problema es que el tipo de contact es PKPhysicsContact (como PKPhysicsContact notado), incluso cuando dices explícitamente que es un SKPhysicsContact , y la extensión está en SKPhysicsContact . Tendría que poder hacer una extensión a PKPhysicsContact para que esto funcione. A partir de esta lógica, podemos decir que ningún método de instancia funcionará en SKPhysicsContact extensiones de SKPhysicsContact en este momento. Diría que es un error con SpriteKit, y debes archivar un radar . Los métodos de clase todavía funcionan ya que los llama en la clase misma.

Mientras tanto, deberías poder mover ese método a tu escena u otro objeto y llamarlo allí con éxito.

Para el registro, este no es un problema específico de Swift. Si realiza el mismo método en una categoría Objective-C en SKPhysicsContact obtendrá el mismo bloqueo.

Tengo un método de ayuda que extiende SKPhysicsContact

extension SKPhysicsContact { /// - returns: `[SKPhysicsBody]` containing all the bodies that match `mask` func bodiesMatchingCategory(mask: UInt32) -> [SKPhysicsBody] { let bodies = [bodyA, bodyB] return bodies.filter { ($0.categoryBitMask & mask) != 0 } } }

en didBeginContact() Llamo a este método en el contact pasado.

func didBeginContact(contact: SKPhysicsContact) { let ballMask: UInt32 = 0x1 << 2 let ball = contact.bodiesMatchingCategory(ballMask) ...

A veces recibo este mensaje de error (como 1 en 5) que bloquea la aplicación:

-[PKPhysicsContact bodiesMatchingCategory:]: unrecognized selector sent to instance 0x165f2350

Busqué PKPhysicsContact y es parte de un marco privado ( enlace ). SKPhysicsContact parece que es solo una definición de clase vacía que expone solo ciertas propiedades de PKPhysicsContact .

Siento que este es un truco de Objective-C en el equipo de SpriteKit que rompe el tipeo fuerte de Swift.

¿Ayuda?

¿Cómo me aseguro de recuperar siempre SKPhysicsContact ?

SKPhysicsContact un cheque para probar SKPhysicsContact

let test = contact as Any print("Test is: /(test)") guard test is SKPhysicsContact else { return }

Lo cual atrapa correctamente el tipo de desajuste.

De hecho, NUNCA devuelve un SKPhysicsContact !!?

Intenté hacer esto en Objective-C (como lo sugirió el respondedor) y obtuve el mismo resultado.

Tengo una discusión sobre los foros de desarrolladores de Apple que pueden ayudar a los futuros buscadores de respuestas.

Aquí está el código de Objective-C para referencia:

@interface SKPhysicsContact (MatchingBodies) - (NSArray *)bodiesMatchingCategory:(UInt32)category; @end @implementation SKPhysicsContact (MatchingBodies) - (NSArray *)bodiesMatchingCategory:(UInt32)category { NSArray *bodies = @[self.bodyA, self.bodyB]; NSPredicate *predicate = [NSPredicate predicateWithBlock:^BOOL(SKPhysicsBody *body, NSDictionary *bindings) { return (body.categoryBitMask & category) != 0; }]; NSArray *matching = [bodies filteredArrayUsingPredicate:predicate]; return matching; } @end

Llamado aquí:

-(void)didBeginContact:(SKPhysicsContact *)contact { static const uint32_t MarbleContact = 0x1 <<1; // 2 static const uint32_t GoalContact = 0x1 <<2; // 4 SKPhysicsBody *ball = [contact bodiesMatchingCategory:MarbleContact].firstObject; NSLog(@"Ball: %@", ball); ...

Devuelve este bloqueo:

-[PKPhysicsContact bodiesMatchingCategory:]: unrecognized selector sent to instance 0x17dad9e0 *** Terminating app due to uncaught exception ''NSInvalidArgumentException'', reason: ''-[PKPhysicsContact bodiesMatchingCategory:]: unrecognized selector sent to instance 0x17dad9e0''

Informe de errores añadido para Apple, # 23332190