Обнаружение столкновений в комплекте спрайтов

Я пытаюсь создать простую игру с комплектом спрайтов. Основная идея состоит в том, что есть один игрок, который может прыгать, чтобы избежать блоков. Но у меня есть проблема, я не знаю, как это сделать, когда игрок попадает в блок, игрок исчезает и начинается анимация крови. Прежде всего, я не понимаю, что этот код делает, что я нашел на веб-сайте яблок.

static const uint32_t blockCategory = 0x1 <<0;
static const uint32_t  playerCategory = 0x1 <<1;

Чем я вызываю функцию didBeginContact и помещаю в него NSLOG ( "сделал вызов функции" ). Но я никогда не получаю вывод в своем отладчике.

Вот мой _player и _block код:   - (символ SKSpriteNode *) {

_player = [SKSpriteNode spriteNodeWithImageNamed:@"soldier_run1"];
_player.physicsBody = [SKPhysicsBody bodyWithCircleOfRadius:_player.size.width /2 -5];
_player.physicsBody.dynamic = YES;
_player.physicsBody.usesPreciseCollisionDetection = YES;
_player.physicsBody.friction = 0;
_player.physicsBody.categoryBitMask = playerCategory;
_player.physicsBody.collisionBitMask = blokCategory;
_player.name = @"player";
SKAction *animAction = [SKAction animateWithTextures:playerTextures timePerFrame:0.1      resize:YES restore:YES];

Мой код _player:

[_player runAction:[SKAction repeatActionForever:animAction]];

return _player;
}
-(SKSpriteNode *)block {
_blok = [[SKSpriteNode alloc] initWithColor:[SKColor blackColor] size:CGSizeMake(15, 40)];

//physics
_blok.physicsBody = [SKPhysicsBody bodyWithRectangleOfSize:_blok.size];
_blok.physicsBody.dynamic = NO;
_blok.name = @"block";
_blok.physicsBody.categoryBitMask = blokCategory;
_blok.physicsBody.collisionBitMask = playerCategory;
SKAction *moveBlock = [SKAction sequence:@[
                                          [SKAction moveToX:-20 duration:2] ]];
[_blok runAction:moveBlock ];
return _blok;
}

Также я не совсем понимаю, что делают categoryBitMask и collisionBitMask. После того, как у меня есть эта работа, я хотел бы заставить персонажа исчезнуть с экрана и анимации крови, чтобы начать, но я не знаю, как это сделать. Я думаю, вы должны сделать что-то вроде:      if (_player & _block didcollide) {      } Но я не знаю, как это сделать.

Ответ 1

КатегорияBitMask устанавливает категорию, которой принадлежит спрайт, тогда как collisionBitMask устанавливает категорию, с которой спрайт может сталкиваться и не пропускать их.

Для обнаружения конфликтов вам необходимо установить контактTestBitMask. Здесь вы задаете категории спрайтов, с которыми вы хотите, чтобы контактные делегаты вызывались при контакте.

То, что вы уже сделали, является правильным. Вот несколько дополнений, которые вам нужно сделать:

_player.physicsBody.contactTestBitMask = blockCategory;
_blok.physicsBody.contactTestBitMask = playerCategory;

Затем выполните делегат-контакт следующим образом:

-(void)didBeginContact:(SKPhysicsContact *)contact`
{
NSLog(@"contact detected");

SKPhysicsBody *firstBody;
SKPhysicsBody *secondBody;

if (contact.bodyA.categoryBitMask < contact.bodyB.categoryBitMask)
{
    firstBody = contact.bodyA;
    secondBody = contact.bodyB;
}
else
{
    firstBody = contact.bodyB;
    secondBody = contact.bodyA;
}

//Your first body is the block, secondbody is the player.
//Implement relevant code here.

}

Для хорошего объяснения при внедрении обнаружения столкновений просмотрите этот учебник.

Ответ 2

Обработка столкновений немного беспорядочна.:) Существует несколько подходов, но одно место, которое вы должны начать, - это этот довольно простой пример от Apple. Чтение дает хорошее введение, а затем вы можете начать ковать с кодом.

Другой подход (который Apple упоминает в своем руководстве) заключается в использовании Double Dispatching (см. wikipedia для длинного описания). Я бы не начал, пытаясь понять этот подход. Это несколько продвинутый подход, учитывая, что он зависит от динамических селекторов и подобных методов, позволяющих совершать магию. Однако даже с этим предостережением вы можете найти простой пример, который кто-то собрал, как это сделать, а также много вспомогательного описания здесь.