检查数组中对象之间冲突的好方法是什么?

时间:2012-10-09 11:39:39

标签: objective-c ios arrays game-physics physics-engine

我一直在另一个for循环中进行for循环,以便同时从数组中获取2个对象,但必须有更好的方法。我只想检查它们是否发生碰撞,然后从视图和数组中删除它们。

4 个答案:

答案 0 :(得分:5)

你在问题​​中使用了collide这个词而没有告诉我们你的意思 - 这就是为什么其他答案到目前为止没有帮助:)他们谈论的是碰撞中的'重复项目字典/数组'但你的意思是在overlay on the screen中碰撞。

这可能是进行此测试的最差方式 - 当您获得大量图像时,它会迅速变得太慢。我不禁想到你正试图解决一个已经被比我们任何一个人都聪明的人解决的问题 - 你想要做什么正好 - 可能是一个完整的物理引擎可能是实现最终目标的更好方法吗?

例如,看看spatial hash data structure used by chipmunk - 这将创建一个包含所有对象的树 - 不在树的同一叶子中的对象不会发生碰撞,因此您可以快速减少比较。但是,该链接有一些图表可以比我在这里更好地解释原理:)

如果您还没有,可以尝试这样做以优化内循环:

// Compare each image with the others to see if they overlap
NSMutableSet *colliding = [NSMutableSet new];
for (NSInteger indexA = 0; indexA < myImages.count; ++indexA) {
    UIView *a = [myImages objectAtIndex:indexA];
    CGRect rectA = a.frame;

    for (NSInteger indexB = indexA; indexB < myImages.count; ++indexB) {
        UIView *b = [myImages objectAtIndex:indexB];
        if (a==b) continue;

        CGRect rectB = b.frame;
        CGRect intersection = CGRectIntersect(rectA, rectB);
        if (NO == CGRectIsNull(intersection)) {
            [colliding addObject:a];
            [colliding addObject:b];
        }
    }
}

// Remove the colliding images
for (UIView *c in colliding) {
    [c removeFromSuperview];
    [myImages removeObject:c];
}

答案 1 :(得分:0)

您是否正在寻找一种同时查找两个不同阵列中的对象的方法?

如果是这样,我建议您使用indexesOfObjectsPassingTest:的{​​{1}}。

NSArray

然后你可以这样做:

@implementation NSArray (Comparison)
- (NSIndexSet *)indexesOfObjects:(NSArray *)objects {
    return [self indexesOfObjectsPassingTest:^(id obj, NSUInteger idx, BOOL *stop) {
        return [objects containsObject:obj];
    }];
}
- (NSArray *)objectsCommonWithArray:(NSArray *)array {
    return [self objectsAtIndexes:[self indexesOfObjects:array]];
}
@end

答案 2 :(得分:0)

NSArray可以使用containsObject:方法代替内循环。但它可能更快(有人应该进行基准测试和查看)将所有对象从一个放入一个集合([NSSet setWithArray:])并循环通过另一个数组,检查它们是否在集合中。或者转换它们并使用intersectSet:(在可变副本上)。我的猜测是,随着数组变大,set方法会更快,但它对你所拥有的数字没有影响。

答案 3 :(得分:0)

您可以使用NSCountedSet

NSArray *array = [[NSArray alloc] initWithObjects:@"1",@"1",@"0",nil];
NSCountedSet *set = [[NSCountedSet alloc] initWithArray:array];
NSLog(@"%@",set); // (1 [2], 0 [1]) // object 1 is collide 
for(id obj in set)
{
    if ([set countForObject:obj]>1) {
        //collide
    }
}