ios - Detección de colisiones en el kit de sprites
objective-c sprite-kit (2)
Intento hacer un juego simple con el kit de sprites. La idea básica es que hay un jugador que puede saltar para evitar bloqueos. Pero tengo un problema. No sé cómo hacer para que, cuando el jugador toque el bloque, el jugador desaparezca y comience la animación de sangre. En primer lugar, no entiendo qué hace este código que encontré en el sitio web de manzanas.
static const uint32_t blockCategory = 0x1 <<0;
static const uint32_t playerCategory = 0x1 <<1;
Entonces estoy llamando a la función didBeginContact y puse un NSLOG ("funcionó llamada") en él. Pero nunca recibo la salida en mi depurador.
Aquí está mi _player y _block code: - (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 restore: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 categoryBitMask y collisionBitMask. Después de tener ese trabajo, me gustaría hacer que el personaje desaparezca de la pantalla y comience la animación de sangre, pero no tengo idea de cómo dejar que eso suceda. Creo que tienes que hacer algo como: if (_player && _block didcollide) {} Pero no sé cómo hacerlo exactamente.
Manejar colisiones es un poco desordenado. :) Hay una serie de enfoques, pero un lugar donde deberías comenzar es este ejemplo bastante simple de Apple. El archivo léame proporciona 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 comenzaría tratando de asimilar ese enfoque. Es un enfoque algo avanzado dado que depende de selectores dinámicos y técnicas similares para permitir que la magia tenga lugar. Sin embargo, incluso con esa advertencia, puede encontrar un ejemplo simple que alguien formó sobre cómo hacerlo, junto con una gran cantidad de descripción de apoyo aquí .
La categoryBitMask establece la categoría a la que pertenece el sprite, mientras que collisionBitMask establece la categoría con la que el sprite puede colisionar y no pasar a través de ellos.
Para la detección de colisiones, necesita establecer contactTestBitMask. Aquí, establece las categorías de sprites con los que desea que se llame a los delegados de contacto al contactarse.
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 una buena explicación sobre la implementación de la detección de colisión, mira este tutorial.