Take the 2-minute tour ×
Game Development Stack Exchange is a question and answer site for professional and independent game developers. It's 100% free, no registration required.

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);
    [self addChild:redEnemySprite];

    //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 addChild:player];
    [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);
[self addChild:redEnemyBulletSprite];

[bulletArray addObject:redEnemyBulletSprite];

//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 addChild:playerSprite z:-3];

    [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
share|improve this question

closed as off-topic by Byte56 Feb 25 at 2:52

This question appears to be off-topic. The users who voted to close gave this specific reason:

  • "Questions about debugging a problem in your project must present a concise selection of code and context so as to allow a reader to diagnose the issue without needing to read all of your code or to engage in extensive back-and-forth dialog. For more information, see this meta thread." – Byte56
If this question can be reworded to fit the rules in the help center, please edit the question.

add comment

1 Answer 1

up vote 0 down vote accepted

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.

share|improve this answer
    
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
add comment

Not the answer you're looking for? Browse other questions tagged or ask your own question.