views:

231

answers:

1

So I'm trying to do collision detections between sprites in cocos 2d. Although I think I may be asking too much as it crashes and the compiler doesn't give me an error, the iPhone simulator just freezes and then gives up. There's a lot of looping involved so I'm guessing it's just too much... but I can't be certain.

My intention was to work it like this.

  • Each Sprite can belong to a collision group, so I can be specific about what collides with what.

  • I have an array called collisionGroups, which contains an array of all Sprites in that group.

  • I have an array called collisionPairs, which holds Arrays like [1,3][3,7][1,7]...

  • At regular intervals, I want to loop through all the collisionGroup pairs, and all the sprites in those groups to check for basic CGRectIntersectsRect.

Alas, I never got that far, that's where it crashes, without any helpful advice from the compiler. Before I set about trying to do this out a different way, am I right in thinking that it's just too much to loop through? Or is something else the problem?

Here's all the code for the collision controller.

@implementation CollisionsController

-(id) init
{
    if((self == [super init])){

     int collisionCapacity = 10;

     NSNotificationCenter *NC = [NSNotificationCenter defaultCenter];
     [NC addObserver:self selector:@selector(registerSpriteForCollisions:) name:@"REGISTER_SPRITE_FOR_COLLISIONS" object:nil];
     collisionGroups =  [NSMutableArray arrayWithCapacity:collisionCapacity];
     collisionPairs =  [NSMutableArray arrayWithCapacity:collisionCapacity];

     // fill up the arrays with Arrays to be used
     for(int i = 0; i <= collisionCapacity; i++){
      NSNumber *dummyValue = [NSMutableArray arrayWithCapacity:100];
      [collisionGroups addObject:dummyValue];
     }
    }
    return self;
}

// ------------------------------------------------------------------------------------------------------------------------------------------------------------



-(void) registerSpriteForCollisions:(NSNotification *)sprite
{

    GIAtlasSprite *cSprite = [sprite object];

    int colIndexInt = [cSprite getCollisionGroup];
    [[collisionGroups objectAtIndex:colIndexInt] addObject:cSprite];

}



// ------------------------------------------------------------------------------------------------------------------------------------------------------------



-(void) handleCollisionsBetweenGroup:(int)groupA andGroup:(int)groupB
{
    NSNumber *numberA = [NSNumber numberWithInt:groupA];
    NSNumber *numberB = [NSNumber numberWithInt:groupB];

    BOOL safeToAdd = YES;

    for(NSArray *pair in collisionPairs){
     if(([pair objectAtIndex:0] == numberA && [pair objectAtIndex:1] == numberB) || ([pair objectAtIndex:0] == numberB && [pair objectAtIndex:1] == numberA)){
      safeToAdd = NO;
      break;
     }
    }

    if(safeToAdd){
     NSArray *pairArray = [NSArray arrayWithObjects:numberA, numberB, nil]; 
     [collisionPairs addObject:pairArray];
    }

}



// ------------------------------------------------------------------------------------------------------------------------------------------------------------



-(void) checkCollisions
{

    for(NSArray *cp in collisionPairs){
     // WHEEEEEEEEE! CRASH!
    }

}


@end

The Stack trace gives me this

#0  0x936f768c in objc_msgSend
#1  0x00006b1f in -[CollisionsController checkCollisions] at CollisionsController.m:90
#2  0x00005359 in -[BownceLevel tick:] at BownceLevel.m:103
#3  0x0004fc0d in -[Timer fire:] at Scheduler.m:87
#4  0x000507a6 in -[Scheduler tick:] at Scheduler.m:215
#5  0x0002ca51 in -[Director mainLoop] at Director.m:229
#6  0x96e56483 in __NSFireTimer
#7  0x903a98f5 in CFRunLoopRunSpecific
#8  0x903a9aa8 in CFRunLoopRunInMode
#9  0x31566600 in GSEventRunModal
#10 0x315666c5 in GSEventRun
#11 0x30a4eca0 in -[UIApplication _run]
#12 0x30a5a09c in UIApplicationMain
#13 0x000029a4 in main at main.m:13

I've absolutely no idea where to start with the Stack trace. All I know is that adding the for loop in checkCollisions is what causes the crash. As always, any help or guidance is appreciated muchly.

+2  A: 

collisionGroups and collisionPairs should be retained when you create them or else they will end up being freed by the autorelease pool in the run loop. Change the declarations to:

collisionGroups =  [[NSMutableArray arrayWithCapacity:collisionCapacity] retain];
collisionPairs =  [[NSMutableArray arrayWithCapacity:collisionCapacity] retain];

and of course, release them in the -dealloc.

codelogic
ahhhhh, right. Memory Management is new to me. Thanks.
gargantaun