SKPhysicsContactDelegate не работает

У меня есть следующий код:

в моей сцене:

static const uint32_t enermyCategory    =  0x1 << 0;
static const uint32_t fatherCategory    =  0x1 << 1;

self.physicsWorld.contactDelegate = self;

    //init ship
Ship *ship = [Ship getFather];
ship.position = CGPointMake(CGRectGetMaxX(self.frame) - ship.frame.size.width , ship.frame.size.height);
[self addChild: ship];

    //init enermy
    Enermy *ene = [[Enermy alloc] initWithImageNamed:enermyName gameScene:self];
ene.position = ship.position;
[self addChild:ene];

#pragma mark - Physics Delegate Methods
- (void)didBeginContact:(SKPhysicsContact *)contact{
    NSLog(@"contact detected");
}

Как видите, для начала я установил и корабль, и энергию в одном месте, поэтому они всегда будут сталкиваться.

Для обоих классов у меня есть следующий код в их методе init:

//setup physics body
self.physicsBody = [SKPhysicsBody bodyWithRectangleOfSize:self.size];
self.physicsBody.dynamic = NO;
self.physicsBody.categoryBitMask = enermyCategory; #shipCategory for ship
self.physicsBody.collisionBitMask = 0;
self.physicsBody.contactTestBitMask = shipCategory; #enermyCategory for ship

Я обнаружил, что NSLog никогда не вызывается, так что физическое обнаружение столкновений никогда не работает, я много читал из руководств Apple для разработчиков, и кажется, что все то же самое, что и у них, не знаю, почему не работает. Я вижу, как изображения корабля и энергии на экране сталкиваются друг с другом.

2 ответа

Решение
self.physicsBody.dynamic = NO;

Статические (нединамические) тела не генерируют контактные события. Сделайте их динамичными.

Кроме того, я вижу, что вы передаете gameScene экземпляру Enemy. Если у врага сильная ссылка на игровую сцену (ивара), то вы можете создавать здесь цикл сохранения (враг сохраняет сцену, сцена сохраняет врага).

В Sprite Kit вы можете просто использовать self.scene чтобы получить доступ к сцене и, если вам нужна сцена во время инициализации, переместите этот код в метод установки и вызовите [ene setup] сразу после добавления его в качестве дочернего для выполнения действий по настройке сцены.

Если для PhysicsBody установлено значение dynamic = NO, это не влияет на контакты. Скорее всего, вы устанавливаете одинаковые contactBitMask и categoryBitMask для обоих узлов. Вы должны настроить корабль, чтобы иметь следующее:

self.physicsBody.categoryBitMask = shipCategory;
self.physicsBody.collisionBitMask = 0;
self.physicsBody.contactTestBitMask = enermyCategory;

Враг должен иметь следующее:

self.physicsBody.categoryBitMask = enermyCategory;
self.physicsBody.collisionBitMask = 0;
self.physicsBody.contactTestBitMask = shipCategory;

Итог: их надо поменять местами на корабле.

Другие вопросы по тегам