SpriteKit — определяет, сталкивается ли узел с другими дочерними узлами, и выполняет действие

У меня есть узел Cat и узел Bird. Узлы-птицы вложены вместе в узел-контейнер, называемый BirdBlock. Все содержится в WorldNode. Если я добавлю птицу в WorldNode, Cat сможет взаимодействовать с ней соответствующим образом, но когда птицы находятся в birdBlock, Cat просто отталкивает их в сторону, и они летят.

Я использую следующее, чтобы найти моих птиц:

[worldNode enumerateChildNodesWithName:kBirdName usingBlock:^(SKNode *node, BOOL *stop)
{
    SKSpriteNode *newBird = (SKSpriteNode *)node;
    if (CGRectIntersectsRect(newBird.frame,cat.frame))
    { 
       //Do Something
       //This is never reached when the birds are in the SKSpriteNode birdBlock. 
       //They just get shoved all over the screen.
    }
}];

Птицы в блоке имеют правильное название.

Сейчас они пересчитываются, но по-прежнему не взаимодействуют с кошкой, кроме как летают по экрану.

Теперь я делаю это:

[[worldNode children] enumerateObjectsUsingBlock:^(id obj, NSUInteger idx, BOOL *stop)
{
        SKSpriteNode *blockNode = (SKSpriteNode *)obj;
        if ([blockNode.name isEqualToString:kBirdBlockName])
        {
            [blockNode enumerateChildNodesWithName:kBirdName usingBlock:^(SKNode *node, BOOL *stop)
            {
                SKSpriteNode *nbird = (SKSpriteNode *)node;
                NSLog(@"FOUND BIRDS HERE");

                //THIS IS FOUND! But below still does not work

                if (CGRectIntersectsRect(nbird.frame, cat.frame))
                {
                    NSLog(@"Hit BIRD");
                    [nbird removeFromParent];
                }
            }
        }
}];

Так что это тоже не работает. Как изменить систему координат спрайта?


person Siriss    schedule 04.12.2014    source источник


Ответы (2)


Вы можете выполнять поиск по дереву узлов разными способами. документация SKNode ясно объясняет это в разделе Поиск в дереве узлов.

Если у вас есть узел с именем @"node", вы можете выполнить поиск по всем потомкам, поставив // перед именем. Таким образом, вы должны искать @"//node".

Попробуйте изменить константу kBirdName на @"//my_bird_name".

Пример использования строкового литерала:

[worldNode enumerateChildNodesWithName:@"//nodeName" usingBlock:^(SKNode *node, BOOL *stop)
{ // Do stuff here... }
person Bamsworld    schedule 04.12.2014
comment
Буквальное, похоже, не работает и, похоже, также ломает птиц, которых нет в блоке. Теперь кошка отправляет их всех в полет вместо того, чтобы выполнять то действие, которое я хочу. - person Siriss; 04.12.2014
comment
Птицы в гнезде появляются в квартале? Кроме того, когда вы обнаруживаете пересечение фреймов, убедитесь, что прямоугольники находятся в одном и том же пространстве координат узлов. Я предполагаю, что cat.frame находится в координатах сцены, но newBird.frame находится в координатном пространстве своих родителей, которое не является сценой (если оно находится в гнезде). При столкновении вам также может понадобиться удалить птицу из родителя, преобразовать положение и добавить в сцену, в зависимости от того, какое поведение вы хотите. - person Bamsworld; 04.12.2014
comment
Что ты имеешь в виду, когда говоришь? Они видны и летят, когда Кот их бьет. Как мне сделать их в одном координатном пространстве? - person Siriss; 04.12.2014
comment
Извините за путаницу. Поднявшись, я имел в виду, что в коде все птичьи узлы теперь обнаруживаются с помощью опубликованного вами метода и передаются в блок через аргумент SKNode * node. SKNode имеет несколько методов преобразования координат в координаты других узлов. Используемые методы: convertPoint:fromNode: и convertPoint:toNode: - person Bamsworld; 05.12.2014
comment
Птицы не учитываются. Как вы перечисляете детей детей? - person Siriss; 05.12.2014
comment
Хорошо, я обновил свой вопрос своим новым кодом. Мне почему-то кажется, что это трудный путь. Теперь я думаю, что это может быть связано с проблемами преобразования координат. - person Siriss; 05.12.2014

Я не мог заставить это работать, поэтому я просто дал всем птицам физическое тело и переместил обнаружение на didBeginContact.

Теперь неважно, кто их родитель, и мне не нужно беспокоиться об изменении координат.

- (void)didBeginContact:(SKPhysicsContact *)contact
{
    SKSpriteNode *firstNode = (SKSpriteNode *)contact.bodyA.node;
    SKSpriteNode *secondNode = (SKSpriteNode *) contact.bodyB.node;
    if ((firstNode.physicsBody.categoryBitMask == catCategory && secondNode.physicsBody.categoryBitMask == birdCategory) || (firstNode.physicsBody.categoryBitMask == birdCategory && secondNode.physicsBody.categoryBitMask == catCategory))
    {
        NSLog(@"DID HIT BIRD");
        if (firstNode.physicsBody.categoryBitMask == catCategory) {
            //do something to secondNode.
        }
        if (firstNode.physicsBody.categoryBitMask == birdCategory) {
            //do something to firstNode.
        }

    }
}
person Siriss    schedule 07.12.2014