Question

I'm building a simple 2D game in Cocos2d which involves having enemies cross the screen across different, predefined paths. The nextFrame method has the following code:

    int indexCount = 0;
for (Enemy *e in enemies) {

    if ([cocosGuy doesCollideWithRect: [e boundingBox]])
    {
        for (Enemy *e in enemies)
        {
            [self removeChild: e cleanup: YES];
        }
        [self startGame];
    }
    // ^ This code not relevant to the question
    if ([e numberOfRunningActions] == 0)
    {
        [e setPosition: [[enemy_positions objectAtIndex:indexCount] CGPointValue]];
        [e runAction: [beziers objectAtIndex: indexCount]];
    }
    ++indexCount;
}

The code in the second if statement above is intended to take a CGPoint from the 'enemy_positions' array and a CCActionInterval from the 'beziers' array. It works - when an enemy completes its path, it is repositioned and the action reruns. But why doesn't this break after the action runs for the first time? Aren't CCActions supposed to be one time only?

I ask because I want to refactor the position and action into a single struct, and I want to make sure I know what's going on first. Am I misunderstanding the CCAction class?

Also, here is the current factory method for generating the 'beziers' array:

-(NSArray*) makeBeziers {

ccBezierConfig bezierconf1;
bezierconf1.controlPoint_1 = ccp(-200, 5);
bezierconf1.controlPoint_2 = ccp(300, 100);
bezierconf1.endPosition = ccp(1000,5);

ccBezierConfig bezierconf2;
bezierconf2.controlPoint_1 = ccp(-200, 5);
bezierconf2.controlPoint_2 = ccp(300, 100);
bezierconf2.endPosition = ccp(1000,5);

ccBezierConfig bezierconf3;
bezierconf3.controlPoint_1 = ccp(-200, 5);
bezierconf3.controlPoint_2 = ccp(300, 100);
bezierconf3.endPosition = ccp(1000,5);

NSArray *myarray;

myarray = [[NSArray arrayWithObjects: [CCBezierBy actionWithDuration:3 bezier: bezierconf1],
                [CCBezierBy actionWithDuration:3 bezier: bezierconf2],
                [CCBezierBy actionWithDuration:3 bezier: bezierconf3],
                nil] retain];
return myarray;
}
Was it helpful?

Solution

This works "by accident". Actions are supposed to be one time only. After they've run, they will be released.

However since you store the actions in a separate array, those actions are retained. Therefore you can re-run them. This might work for some actions, other actions may show subtle issues, and some actions may not do anything, leak memory or crash immediately if you do so.

Re-using actions is generally considered bad practice, unless you know the code of each action and you have verified that reusing it doesn't do anything "bad".

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top