如何检测连续相互接触的相同类型的节点(SpriteKit)

时间:2015-07-23 14:15:29

标签: ios objective-c sprite-kit game-physics skspritenode

实际上这是一个算法和实现问题。

我有一个节点数组,这些节点有3种类型。他们独特的特色是他们的颜色。

我想检测一下,如果有几个相同的节点连续触摸它们以创建一个关节或类似的东西。

例如,假设我的阵列中有一堆球,可以是3种颜色的红色,蓝色,绿色。我想找到有5个元素的关节。

我尝试了迭代遍历数组的递归方式。但它有时有时无效。所以我认为我做的方式有一些缺陷。

- (void) findAdjacentNode:(BallSpriteNode*) currentNode from:(NSMutableArray*)currentNodes{

    for (BallSpriteNode *node in currentNodes) {
        float distance = [self getDistanceBetween:node.position and:currentNode.position];

        if ( distance - (node.size.width/2 + currentNode.size.width/2 ) <= 0
            && [node.currentColor isEqual:((BallSpriteNode*)currentNode).currentColor]
            && ![node isEqual:currentNode]
            && ![sameColorNodes containsObject:node])
        {
            [sameColorNodes addObject:node];
            [self findAdjacentNode:node from:currentNodes];
        }
    }

    if (sameColorNodes.count >=5) {
        [self removeSelectedNodesFromArray:sameColorNodes];
        return;
    }
}

赞赏任何形式的帮助和领导。

我已经达成解决问题但仍有一点问题随机出现。我的SKSpriteNode子类有isRemoved变量来跟踪节点是否被删除。我看到我的问题一次又一次地删除相同的节点,所以无限循环。

修改 通过改变我的实现如下,我解决了我的主要问题,它已经很好了。

if (sameColorNodes.count >=5) {
    bool isEligibleToRemove = YES;
    for (BallSpriteNode *node in sameColorNodes) {
        if (node.isRemoved) {
            isEligibleToRemove = NO;
            break;
        }
    }

    if(isEligibleToRemove){
        NSLog(@"%@",sameColorNodes);
        [self removeSelectedNodesFromArray:sameColorNodes];
    }
}

现在我正在处理一个随机发生的问题并且很难捕捉到。有时我的方法无法将一些节点添加到sameColorNodes数组,即使它们应该在其中。例如,如果其中9个形成一个组,则其中有8个。但如果它有5个节点,它每次都能正常工作。

编辑2:

这是我的算法的最终版本。我测试了它并且工作正常。如果为某个数组中的所有节点调用此方法。它将找到所有相同颜色的节点,并通过相互触摸创建路径。

- (void) findAdjacentNode:(BallSpriteNode*)currentNode from:(NSMutableArray*)currentNodes{

    recursiveCount ++;

    if(![sameColorNodes containsObject:currentNode]){
        [sameColorNodes addObject:currentNode];
    }

    for (BallSpriteNode *node in currentNodes) {
        float distance = [self getDistanceBetween:node.position and:currentNode.position];

        if (node.ballType == BrickBall) {
            continue;
        }

        if (distance - (node.size.width/2 + currentNode.size.width/2) <= 0
            && [node.currentColor isEqual:((BallSpriteNode*)currentNode).currentColor]
            && ![node isEqual:currentNode]
            && ![sameColorNodes containsObject:node])
        {
            [sameColorNodes addObject:node];
            [self findAdjacentNode:node from:currentNodes];
        }
    }

    recursiveCount --;

    if (sameColorNodes.count >=5 && recursiveCount == 0) {
        bool isEligibleToRemove = YES;
        for (BallSpriteNode *node in sameColorNodes) {
            if (node.isRemoved) {
                isEligibleToRemove = NO;
                break;
            }
        }

        if(isEligibleToRemove){
            NSLog(@"%@",sameColorNodes);
            [self removeSelectedNodesFromArray:sameColorNodes];        
        }
    }
}

1 个答案:

答案 0 :(得分:1)

<强>更新

以下群组靠近并具有相同currentColor属性的精灵。它创建了一个字典,其中包含sprite的索引作为键,以及一个匹配的sprite作为对象的数组:

- (CGFloat) getDistanceBetween:(CGPoint)point1 and:(CGPoint)point2 {
    CGFloat dx = point1.x - point2.x;
    CGFloat dy = point1.y - point2.y;
    return sqrt(dx*dx+dy*dy);
}

- (void) countMatches:(NSMutableArray*)currentNodes {
    NSMutableDictionary *colorCount = [NSMutableDictionary dictionary];
    NSMutableArray *nodes = [currentNodes mutableCopy];
    for (NSUInteger i=0;i<nodes.count;i++) {
        BallSpriteNode *ball1 = [nodes objectAtIndex:i];
        NSNumber *key = [NSNumber numberWithUnsignedInteger:i];
        for (NSUInteger j=nodes.count-1;j>i;j--) {
            BallSpriteNode *ball2 = [nodes objectAtIndex:j];
            float distance = [self getDistanceBetween:ball1.position and:ball2.position];
            if (distance - (ball2.size.width/2 + ball1.size.width/2) <= 0
                && [ball2.currentColor isEqual:ball1.currentColor]) {
                NSMutableArray *nodeArray = [colorCount objectForKey:key];
                if (!nodeArray) {
                    nodeArray = [NSMutableArray arrayWithCapacity:5];
                }
                [nodeArray addObject:ball2];
                [colorCount setObject:nodeArray forKey:key];
                [nodes removeObjectAtIndex:j];
            }
        }
        NSMutableArray *nodeArray = [colorCount objectForKey:key];
        if (nodeArray) {
            [nodeArray addObject:ball1];
            [colorCount setObject:nodeArray forKey:key];
        }
    }

    [colorCount enumerateKeysAndObjectsUsingBlock:^(id key, id obj, BOOL *stop) {
        NSArray *array = obj;
        if (array.count >= 5) {
            // Add code to join the nodes here
            NSLog(@"color: %@ count: %ld", key, array.count);
        }
    }];
}