Search code examples
objective-ccocos2d-iphonecollision-detectionbox2d-iphone

Simple collision detection in cocos2d box2d..nothing happens on collision


I'm trying to figure out how to do this, I have a sprite called 'player' and sprites called 'rock' I'm trying to detect collision between both sprites..... but nothing happens on collision!

heres what i have done:

-(void)addRock {

rock = [CCSprite spriteWithFile:@"rock.png" 
                                     rect:CGRectMake(0, 0, 27, 40)]; 

// Determine where to spawn the target along the X axis
CGSize winSize = [[CCDirector sharedDirector] winSize];
int minX = rock.contentSize.width/2;
int maxX = winSize.width - rock.contentSize.width/2;
int rangeX = maxX - minX;
int actualX = (arc4random() % rangeX) + minX;
// Create the target slightly off-screen along the right edge,
// and along a random position along the X axis as calculated above
rock.position = ccp(actualX, 500);
rock.tag = 1;
[rockArray addObject:rock];
[self addChild:rock];

player code below:

-(id) init{
if( (self=[super initWithColor:ccc4(255, 255, 255, 255)] )) {
    CGSize winSize = [[CCDirector sharedDirector] winSize];
    player = [CCSprite spriteWithFile:@"Player.png" 
                                           rect:CGRectMake(0, 0, 27, 40)];
    player.position = ccp(winSize.width/2, winSize.height/4+15); //position of where the player is placed
    player.tag = 2;
    [playerArray addObject:player];
    [self addChild:player];

sprite move finished:

-(void)spriteMoveFinished:(id)sender {


CCSprite *sprite = (CCSprite *)sender;
[self removeChild:sprite cleanup:YES];

if (sprite.tag == 1) { // rock
    [rockArray removeObject:sprite];
} else if (sprite.tag == 2) { // players
    [playerArray removeObject:sprite];

init (array initialisation):

rockArray = [[NSMutableArray alloc]init];
    playerArray = [[NSMutableArray alloc]init];
    [self schedule:@selector(update:)];

update method

- (void)update:(ccTime)dt {


    NSMutableArray *rocksToDelete = [[NSMutableArray alloc] init];
    for (rock in rockArray) {
        CGRect rockRect = CGRectMake(
                                       rock.position.x - (rock.contentSize.width/2), 
                                       rock.position.y - (rock.contentSize.height/2), 
                                       rock.contentSize.width, 
                                       rock.contentSize.height);


    NSMutableArray *playersToDelete = [[NSMutableArray alloc] init];
    for (player in playerArray) {
        CGRect pRect = CGRectMake(

                                        player.position.x - (player.contentSize.width/2), 
                                        player.position.y -(player.contentSize.height/2), 
                                        player.contentSize.width,
                                        player.contentSize.height);

        if (CGRectIntersectsRect(rockRect, pRect)) {
            [rocksToDelete addObject:rock];
        }

        for (rock in rocksToDelete) {
            [rockArray removeObject:rock];
            [self removeChild:rock cleanup:YES];                                    
        }

        if (rocksToDelete.count > 0) {
            [playersToDelete addObject:player];
        }
        [rocksToDelete release];

        for (player in playersToDelete) {
            [playerArray removeObject:player];
            [self removeChild:player cleanup:YES];
        }
        [playersToDelete release];

I have been trying to sort my problem all night. I can seem to get the collision detection working. If so, can someone show me a brief code?


Solution

  • well to check for collision between the two sprites you'll have to call a method every frame (or how ever often you choose) to check if collision has occurred. Add Following code to the init method:

    [self scheduleUpdate];
    

    ...this will call following method (you have to add to your class implementation) on every frame:

    -(void)update:(ccTime)delta {
       if (CGRectIntersectsRect(player.boundingBox, rock.boundingBox)) {
           //Do Stuff
       }
    }
    

    For the previous code to work you'll have to declare the Player and Rock sprite as member variables so they can be used throughout the class.

    If you have more than one rock sprite in the scene you want to check collisions with you'll have to use an array. Quick example:

    1 Declare an array in you class interface:

    NSMutableArray *rockArray;
    

    2 Allocate memory for it in the init method

    rockArray = [NSMutableArray array];
    

    3 In the "addRock" method add the created rock sprite to the array and then as a child to the scene

    -(void) addRock {
       CCSprite *rock = [CCSprite spriteWithFile:@"rock.png" 
                                         rect:CGRectMake(0, 0, 27, 40)];
       //...
    
       [rockArray addObject:rock];
       [self addChild:[rockArray lastObject]];
    }
    

    4 In the "update" method you now loop through the array and check for collision between rock & player

    for (CCSprite *_rock in rockArray) {
       if (CGRectIntersectsRect(player.boundingBox, rock.boundingBox)) {
               //Do Stuff e.g remove that rock from the scene
               [self removeChild:_rock cleanup:YES];
           }
    }
    

    Hope this helps ;-) Feel free to ask any questions