访问所有具有相同 categoryBitMask 的单个对象

Accessing individual objects that all have the same categoryBitMask

我有几个游戏世界对象,玩家需要在 physicsBody.categoryBitMask 联系它们时单独与之交互。我没有为每个单独的对象使用单独的 categoryBitMask(对象数量超过 categoryBitMask 的限制,即 32),而是使用 1 个 categoryBitMask 并为所有对象单独命名。这是它在代码中的样子:

-(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.");
        }
}

问题是,在 didBeginContact 方法中,当玩家接触任何对象时,所有代码都会被执行。甚至是玩家尚未接触过的对象的代码。这意味着 IF 语句,例如 if ([_backgroundLayer childNodeWithName:@"slope"]) 是不完整的。有人能告诉我如何正确写出单个对象接触的 IF 语句吗? didBeginContact 中的以下 IF 语句也不起作用:

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

您的 if 语句都只是检查子项是否存在,它们似乎都这样做了。我想你想检查的是碰撞节点是否有你要找的名字,所以改变:

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

至:

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