Detección de colisiones en sprite kit

Estoy tratando de hacer un juego simple con sprite kit. La idea básica es que hay un jugador que puede saltar para evitar lockings. Pero tengo un problema. No sé cómo hacer que cuando el jugador golpee el bloque, el jugador desaparece y comienza la animation de sangre. En primer lugar, no entiendo qué hace este código que encontré en el website de Apple.

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

Que estoy llamando a la function didBeginContact y pongo una NSLOG ("did call function") en ella. Pero nunca recibo el resultado en mi depurador.

Aquí está mi código _player y _block: – (SKSpriteNode *) character {

 _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 restre:YES]; 

Mi código de jugador:

 [_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; } 

Además, realmente no entiendo qué hacen la categoría BitMask y collisionBitMask. Después de tener ese trabajo me gustaría hacer que el personaje desapareciera de la pantalla y comenzara la animation de sangre, pero no tengo idea de cómo dejar que eso ocurra. Creo que tienes que hacer algo como: if (_player && _block didcollide) {} Pero no sé cómo hacerlo exactamente.

La categoría BitMask establece la categoría a la que pertenece el sprite, mientras que el collisionBitMask establece la categoría con la que el sprite puede colisionar y no traspasarlos.

Para la detección de colisiones, debe establecer contactTestBitMask. Aquí, establece las categorías de sprites con los que desea que se llame a los delegates de contacto.

Lo que ya has hecho es correcto. Aquí hay algunas adiciones que debe hacer:

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

Luego, implemente el delegado de contacto de la siguiente manera:

 -(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. } 

Para get una buena explicación sobre cómo implementar la detección de colisiones, consulte este tutorial.

Manejar colisiones es un poco desorderado. 🙂 Hay varios enfoques, pero un lugar con el que debe comenzar es este ejemplo bastante simple de Apple. El readme ofrece una buena introducción, y luego puede comenzar a hurgar con el código.

Otro enfoque (que Apple menciona en su guía) es utilizar Double Dispatching (ver wikipedia para una descripción larga). Sin embargo, no empezaré por tratar de entender ese enfoque desde el principio. Es un enfoque algo avanzado dado que depende de selectores dynamics y técnicas similares para permitir que la magia tenga lugar. Sin embargo, incluso con esa advertencia, puedes encontrar un ejemplo simple que alguien ha elaborado sobre cómo hacerlo, junto con una gran cantidad de descripción de apoyo aquí .