Am I asking too much with my collision detection method for Cocos2d?
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 Bownc开发者_开发知识库eLevel.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.
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
.
精彩评论