# cocos2d collision detection between two ccsprites i am using boundingBox but this method is not working [closed]

I am making a cocos2d side scroller and I am currently putting collision detection in. I have an enemy that shoots at the player. I want to have the bullets disappear when they hit the player. The enemy itself disappears when it touches the player but for some reason the bullet collision detection does not work. Here is the code for the enemy, bullets, and collision detection.

@implementation RedEnemy
@synthesize redEnemySprite,redEnemyBulletSprite;

+(id)createRedEnemy{
return [[[self alloc]init]autorelease];
}

-(id)init{
if ((self = [super init])) {
CGSize size = [[CCDirector sharedDirector]winSize];
screenWidth = size.width;
screenHeight = size.height;

//Make the redEnemy
redEnemySprite = [CCSprite spriteWithFile:@"redenemy.png"];
redEnemySprite.position = ccp(screenWidth + 100, screenHeight/2);

//Set the speed of the redEnemy and bullet moving
speed = 15;

//Set the redEnemyFlameCounter
redEnemyFlameCounter = 1;

//Create the array
bulletArray = [[NSMutableArray alloc]init];

//Call the method that moves the redEnemy
[self moveTheRedEnemy];

//Start the redEnemyFlame
[self schedule:@selector(redEnemyFlame:)interval:1.0f/7.0f];

//Shoot the bullets
[self schedule:@selector(shootTheBullets:)interval:1.0f/1.0f];

//Check to see if redEnemy is off screen
[self schedule:@selector(isRedEnemyOffScreen:)interval:1.0f/60.0f];

//Test for bulletcollisions
player = [Player createPlayer];
[self schedule:@selector(testForRedEnemyBulletCollisions:)interval:1.0f/60.0f];

}
return self;
}

-(void)redEnemyFlame:(ccTime)delta{
redEnemyFlameCounter ++;

if (redEnemyFlameCounter % 2){
[redEnemySprite setTexture:[[CCSprite spriteWithFile:@"redenemy2.png"]texture]];
}else{
[redEnemySprite setTexture:[[CCSprite spriteWithFile:@"redenemy.png"]texture]];
}
}

-(void)moveTheRedEnemy{
ccBezierConfig redEnemyPath;
redEnemyPath.controlPoint_1 = ccp(screenWidth - 200, screenHeight + 750);
redEnemyPath.controlPoint_2 = ccp(screenWidth - 400, -1000);
//redEnemyPath.endPosition = ccp(screenWidth/3.4, screenHeight/2);
redEnemyPath.endPosition = ccp(-300, screenHeight + 150);

CCBezierTo* redEnemyBezierPath = [CCBezierTo actionWithDuration:speed    bezier:redEnemyPath];
[redEnemySprite runAction:redEnemyBezierPath];

}

-(void)shootTheBullets:(ccTime)delta{
//Create redEnemyBullets
redEnemyBulletSprite = [CCSprite spriteWithFile:@"thebullet.png"];
redEnemyBulletSprite.position = ccp(redEnemySprite.position.x, redEnemySprite.position.y);

//CCMoveTo* bulletMove = [CCMoveTo actionWithDuration:5.0 position:ccp(player.playerSprite.position.x, player.playerSprite.position.y)];
CCMoveTo* bulletMove = [CCMoveTo actionWithDuration:5.0 position:ccp(-500, redEnemyBulletSprite.position.y)];
[redEnemyBulletSprite runAction:bulletMove];
}

-(void)isRedEnemyOffScreen:(ccTime)delta{
if (redEnemySprite.position.x < -100) {
[self unschedule:@selector(isRedEnemyOffScreen:)];
[self unschedule:@selector(redEnemyFlame:)];
[self unschedule:@selector(shootTheBullets:)];
}

}

-(void)testForRedEnemyBulletCollisions:(ccTime)delta{
if (CGRectIntersectsRect(redEnemyBulletSprite.boundingBox, player.playerSprite.boundingBox)){
wasPlayerHitByRedEnemyBullet = YES;
}
if (wasPlayerHitByRedEnemyBullet) {
redEnemyBulletSprite.visible = NO;
}
}

-(void)dealloc{
[super dealloc];
}
@end


The player is created in a different class. Here is the code.

@implementation Player
@synthesize playerSprite;

+(id)createPlayer{
return [[[self alloc]init]autorelease];
}

-(id)init{
if((self = [super init])){
CGSize size = [[CCDirector sharedDirector]winSize];
screenWidth = size.width;
screenHeight = size.height;

gravity = 2;

playerSprite = [CCSprite spriteWithFile:@"thefinalcharacter.png"];
playerSprite.scale = 1.5;
playerSprite.position = ccp(screenWidth/3.4, screenHeight/2);

[self schedule: @selector(flight:)interval:1.0f/7.0f];

}
return self;
}

-(void)flight:(ccTime)delta{
flightCounter ++;

if (flightCounter % 2){
[playerSprite setTexture:[[CCSprite spriteWithFile:@"thefinalcharacter.png"]texture]];
}else{
[playerSprite setTexture:[[CCSprite spriteWithFile:@"thefinalcharacter2.png"]texture]];
}
//[self schedule:@selector(updatePosition:)interval:1.0f/30.0f];
}

-(void)updatePosition:(ccTime)delta{
if(playerSprite.position.y < 35){
gravity = 0;
}else if(playerSprite.position.y > screenHeight - 150) {
playerSprite.position = ccp(playerSprite.position.x, playerSprite.position.y - 100);
}else{
gravity = 2;
}

playerSprite.position = ccp(playerSprite.position.x, playerSprite.position.y - gravity);
}

-(void)dealloc{
[super dealloc];
}
@end


I am a little confused by the code, but I will do my best to help you.

Well, it looks like your intent was to create a bullet sprite each time the shootTheBullets routine is called, and then add the sprite to your bulletArray. If that is the case you need to change the testForRedEnemyBulletCollisions routine to loop through the bulletArray and check each bullet against the player. Presently your code keeps checking the same instance variable called redEnemyBulletSprite over and over again. This would work fine if you only had one bullet on the screen at any given time, but if that were the case then you would not need a bullet array. The bullet array implies that you want to have multiple bullets at a time.

Now, even if you begin to loop through your array I perceive a problem with your code. First, redEnemyBulletSprite is an instance variable that you use each time you create a bullet, and you keep adding this same instance variable to the same parent and to the same bulletArray. This could have unpredictable results. Also, it is my guess that you only do see one bullet per enemy on the screen at any given time because of this, but that is hard to say by just looking at the code you have posted. Regardless, if this is not your intent then you should instead us a local variable to define your bullet sprite, such as bullet, then add the bullet to the parent and to your bulletArray. Then just simply loop through the bullet array in your testForRedEnemyBulletCollisions routine to check each bullet sprite against the player.

The problem with this approach is that your bulletArray will continue to grow as your game plays on, since you are adding a new bullet to the parent and to the bullet array each time one is fired. This could cause a significant performance issue if you end up with hundreds or potentially even thousands of bullets being fired in a given level. Obviously this depends on the number of enemy ships, their rate of fire, and how long the level lasts.

To avoid this you can remove the bullet from the parent and from the bullet array if it hits the player or leaves the screen. This in my opinion is not the best approach because of potential performance issues, but it will work depending on your particular situation.

Let me know if this helps, or if you need further information.

• Thanks, helped lots. Fixed the problem and array. To figure out the collision I just looped through the array. – PoKoBros Sep 26 '13 at 20:45
• No problem. I don't know then if I answered your question, but if so please mark it as such if you would be so kind. Take care! – Pluvius Sep 26 '13 at 21:46