I have a fairly simple and somewhat cookie cutter method for testCollisions: (FYI: BasicProjectile is a CCNode with a CCSprite member).

    for (BasicProjectile * basicProjectile in self.projectiles) {

        NSLog(@"projectile sprite %@",NSStringFromCGRect(basicProjectile.sprite.boundingBox));
        NSLog(@"destination sprite %@",NSStringFromCGRect(basicProjectile.destination.sprite.boundingBox));

            if (CGRectIntersectsRect(basicProjectile.sprite.boundingBox, basicProjectile.destination.sprite.boundingBox)) {

                [basicProjectile.destination setHealth:(basicProjectile.destination.hp - basicProjectile.damage)];

                [self.projectiles removeObject:basicProjectile];
                [self removeChild:basicProjectile cleanup:YES];


Those NSLog statements output:

2013-03-23 10:02:59.124 GridWars[25268:c07] projectile sprite {{-10, -10}, {20, 20}}

2013-03-23 10:02:59.124 GridWars[25268:c07] destination sprite {{-13.5, -34}, {27, 68}}

The main problem is that the collision immediately happens. It should take a few frames to travel from the source to the destination. So although the logic of setting the health works fine the sprite itself is never seen on the screen because the very second its fired it is removed.
From what I understand about CGRectIntersectsRect those 2 points listed above do not intersect. Am I wrong are they intersecting? What can be causing these projectiles to immediately intersect with their target?

BasicProjectile class (CCNODE superclass)

-(id)initWithSourceAndDestination:(GameCharacters*)Source destination:(GameCharacters*)Destination
    if (self = [super init]) {
        self.damage = 25;
        self.sprite = [CCSprite spriteWithFile:@"Projectile.png"];
        [self addChild:self.sprite z:1000 ];
        self.source = Source;
        self.destination = Destination;
    return self;

GameCharacters would look similar to this except have health and mana properties.

WizardHero Class, Method Fire:

basicProjectile.position = self.position; [self.hostLayer addChild:basicProjectile z:2021];

// Determine where we wish to shoot the projectile to
int realX;

// Are we shooting to the left or right?
CGPoint diff = ccpSub(basicProjectile.destination.position, basicProjectile.source.position);
if (diff.x > 0)
    realX = (self.hostLayer.tileMap.mapSize.width * self.hostLayer.tileMap.tileSize.width) +
} else {
    realX = -(self.hostLayer.tileMap.mapSize.width * self.hostLayer.tileMap.tileSize.width) -
float ratio = (float) diff.y / (float) diff.x;
int realY = ((realX - basicProjectile.position.x) * ratio) + basicProjectile.position.y;
CGPoint realDest = ccp(realX, realY);

// Determine the length of how far we're shooting
int offRealX = realX - basicProjectile.position.x;
int offRealY = realY - basicProjectile.position.y;
float length = sqrtf((offRealX*offRealX) + (offRealY*offRealY));
float velocity = 380/1; // 380pixels/1sec
float realMoveDuration = length/velocity;

// Move projectile to actual endpoint
id actionMoveDone = [CCCallFuncN actionWithTarget:self.hostLayer
[basicProjectile runAction:
 [CCSequence actionOne:
  [CCMoveTo actionWithDuration: realMoveDuration
                      position: realDest]
                   two: actionMoveDone]];

[self.hostLayer.projectiles addObject:basicProjectile];

Basically here is the class structure

Three main superclasses




Then the actual more specific classes (used on the GameLevels)





  • \$\begingroup\$ I think it might have something to do with the way you are calling them... They are both being called basic projectiles from the start of the loop and it looks like you're checking collision with itself because it iterates through all of the basic projectiles in self.projectiles... Try setting up a temp enemy on screen and then check for collision with that and basicprojectole \$\endgroup\$ – Savlon Mar 23 '13 at 20:31
  • \$\begingroup\$ the for loop is fast enumeration of the array of projectiles (in this case its only 1 projectile). In the if(CGRectIntersectsRect) statement it is checking the destination or target of the projectile to see if it collided with it. then the projectile is removed and damage is dealt, along with deleting the projectile. However my problem is that it immediately collides, so the sprite and its animation is not seen \$\endgroup\$ – owen gerig Mar 24 '13 at 20:27
  • \$\begingroup\$ Hmmm... Can you paste the basic projectile code \$\endgroup\$ – Savlon Mar 25 '13 at 0:23
  • \$\begingroup\$ Destination is a subnode of the projectile? If that is the case, if you add a node to another, the parent node always collide to the child node, because is "inside" the parent. How did you place the projectiles/destinations? \$\endgroup\$ – Sebastián Castro Mar 25 '13 at 13:12
  • \$\begingroup\$ destination is a property of projectiles that holds a reference to the GameCharacter located on the GameLayer. The projectile is added to the gamelayer so it is not a subnode (same for the destination (GameCharacter)) \$\endgroup\$ – owen gerig Mar 25 '13 at 17:08

(copied from my other question https://stackoverflow.com/a/15686025/530933)

since your projectiles and targets are inside a separate CCNode, their bounding box returns their position inside their parent and not in actual screen coordinates (which you want in your case).

To convert the pos you can do like this

CGPoint targetPos = [basicProjectile.destination.sprite.parent convertToWorldSpace:basicProjectile.destination.sprite.position];
NSLog(@"targetPos  %@",NSStringFromCGPoint(targetPos));
CGRect targetRect = [self boundingRectForSprite:basicProjectile.destination.sprite andPos:targetPos];

CGPoint projectilePos = [basicProjectile.sprite.parent convertToWorldSpace:basicProjectile.sprite.position];
NSLog(@"projectilePos  %@",NSStringFromCGPoint(projectilePos));
CGRect projectileRect = [self boundingRectForSprite:basicProjectile.destination.sprite andPos:projectilePos];

the boundingRectForSprite method makes the uses the sprite bounding box and position and then calculates the final rect taking anchor point of (0.5,0.5).

now the targetRect and projectileRect are of actual screen coordinates.


Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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