Accessing individual objects that all have the same categoryBitMask

54 views Asked by At

I have several game world objects the player needs to interact with individually upon his physicsBody.categoryBitMask contacting them. Instead of using separate categoryBitMasks for each individual object (object count surpasses categoryBitMask's limit, which is 32) I just use 1 categoryBitMask and gave all the objects individual names. Here's how it looks in code:

-(void)createCollisionAreas
{
    if (_tileMap)
    {
        TMXObjectGroup *group = [_tileMap groupNamed:@"ContactZone"]; //Layer's name.

        //Province gateway.
        NSDictionary *singularObject = [group objectNamed:@"msgDifferentProvince"];
        if (singularObject)
        {
            CGFloat x = [singularObject[@"x"] floatValue];
            CGFloat y = [singularObject[@"y"] floatValue];
            CGFloat w = [singularObject[@"width"] floatValue];
            CGFloat h = [singularObject[@"height"] floatValue];

            SKSpriteNode *object = [SKSpriteNode spriteNodeWithColor:[SKColor redColor] size:CGSizeMake(w, h)];
            object.name = @"provinceGateway";
            object.position = CGPointMake(x + w/2, y + h/2);

            object.physicsBody = [SKPhysicsBody bodyWithRectangleOfSize:CGSizeMake(w, h)];

            object.physicsBody.categoryBitMask       = terrainCategory;
            object.physicsBody.contactTestBitMask    = playerCategory;
            object.physicsBody.collisionBitMask      = 0;
            object.physicsBody.dynamic = NO;
            object.physicsBody.friction = 0;
            object.hidden = YES;

            [_backgroundLayer addChild:object];
        }

        /*More code written below. Too lazy to copy & paste it all*/
}

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


    /**BOUNDARY contacts*/
    if ((firstBody.categoryBitMask == noGoCategory) && (secondBody.categoryBitMask == playerCategory))
    {
        //Boundary contacted by player.
        if ([_backgroundLayer childNodeWithName:@"bounds"])
        {
            NSLog(@"Player contacted map bounds.");
        }
        if ([_backgroundLayer childNodeWithName:@"nogo"])
        {
            NSLog(@"Player can't go further.");
        }
        if ([_backgroundLayer childNodeWithName:@"provinceGateway"])
        {
            NSLog(@"Another province is ahead. Can't go any further.");
        }
        if ([_backgroundLayer childNodeWithName:@"slope"])
        {
            NSLog(@"Player contacted a slope.");
        }
}

The problem is, in didBeginContact method, when the player contacts any object all the code gets executed. Even the code from objects the player hasn't contacted yet. This means the IF statements, such as if ([_backgroundLayer childNodeWithName:@"slope"]), are not complete. Can someone tell me how to properly write out the IF statements for individual object contact? The following IF statement, inside didBeginContact, doesn't work either:

if ([_player intersectsNode:[_backgroundLayer childNodeWithName:@"slope"]])
1

There are 1 answers

1
Good Doug On BEST ANSWER

Your if statements are all just checking if the child exists, which it seems they all do. What I think you want to check is if the collision node has the name you are looking for, so change:

if ([_backgroundLayer childNodeWithName:@"bounds"])

to:

if ([firstBody.node.name isEqualToString:@"bounds"])