Properly setting up SKFieldNode.categoryBitMask & physicsBody.contactTestBitMask

271 Views Asked by At

I'm trying to make an invisible boundary, with the SKFieldNode, that sends an NSLog(@"Contact registered between bird & field node."); through didBeginContact method when a sprite is inside the SKFieldNode radius. I think I set up the code correctly, but nothing's happening when a bird sprite's physicsBody is contacting the radius of the field node:

-(void)didBeginContact:(SKPhysicsContact *)contact
{
    SKPhysicsBody *firstBody, *secondBody; //Create 2 placeholder reference's for the contacting objects.

    if (contact.bodyA.categoryBitMask < contact.bodyB.categoryBitMask) //If bodyA has smallest of 2 bits...
    {
        firstBody   = contact.bodyA; //...it is then the firstBody reference [Smallest of two (category) bits.].
        secondBody  = contact.bodyB; //...and bodyB is then secondBody reference [Largest of two bits.].
    }
    else //This is the reverse of the above code (just in case so we always know what's what).
    {
        firstBody = contact.bodyB;
        secondBody = contact.bodyA;
    }


    if ((firstBody.categoryBitMask == birdCategory) && (secondBody.categoryBitMask == fieldNodeCategory))
    {
        NSLog(@"Contact registered between bird & field node.");
    }
}

-(void)spriteWithFieldNode
{
    //This sprite looks like a worm.
    _sprite = [Sprite node];
    _sprite.position = CGPointMake(self.sprite2.position.x, self.sprite2.position.y);
    [self addChild:_sprite];

    //Field node is attached to the worm sprite & registers a contact if a bird is in its radius.
    SKFieldNode *fieldNode = [SKFieldNode node];
    fieldNode.enabled = YES;
    fieldNode.strength = 0.5f;
    fieldNode.region = [[SKRegion alloc] initWithRadius:50];
    //fieldNode.falloff = 50;
    fieldNode.categoryBitMask = fieldNodeCategory;
    [_sprite addChild:fieldNode];
}

-(void)birdSprite
{
    _bird = [Bird node];
    _bird.position = CGPointMake(self.size.width/2, self.size.height/2);
    [self addChild:_bird];
}

_bird class physicsBody setup:

minDiam = MIN(self.size.width, self.size.height);
minDiam = MAX(minDiam - 16, 4);
self.physicsBody = [SKPhysicsBody bodyWithCircleOfRadius:minDiam/3.0 center:CGPointMake(-9, -2)];
self.physicsBody.categoryBitMask = birdyCategory;
self.physicsBody.contactTestBitMask = boundaryCategory | spriteCategory | someOtherCategory;
self.physicsBody.collisionBitMask = boundaryCategory;
self.physicsBody.fieldBitMask = fieldNodeCategory;

self.physicsBody.allowsRotation = NO;
self.physicsBody.linearDamping = 300;
self.physicsBody.restitution = 0.0f; //bounciness.
self.zPosition = 3.1;
1

There are 1 best solutions below

1
rakeshbs On BEST ANSWER

You can try putting an invisible static physics body of radius equal to the fieldNode, and detect contact of the bird with this body.

SKSpriteNode *fieldBody = [[SKSpriteNode alloc] initWithColor:[UIColor redColor] size:CGSizeZero];
fieldBody.physicsBody = [SKPhysicsBody bodyWithCircleOfRadius:50];
fieldBody.position = _sprite.position
fieldBody.physicsBody.dynamic = NO;
fieldBody.physicsBody.categoryBitMask = fieldNodeCategory;
[self addChild:fieldBody];

And in birdNode setup

self.physicsBody.contactTestBitMask = boundaryCategory | spriteCategory | someOtherCategory | fieldNodeCategory;