views:

32

answers:

1

Of the three parts I want to move, only the last one actually moves. I can't seem to "recycle" the ease action I created.

How is this done the correct way?

- init
{    
    // initial setup

    [self moveParts];
}

- (void)moveParts
{
    id action = [CCMoveBy    actionWithDuration:1 position:ccp(0,160)];
    id ease   = [CCEaseInOut actionWithAction:action];

    [part1 runAction:ease];
    [part2 runAction:ease];
    [part3 runAction:ease];
}
A: 

Seems like it is a problem with allocating and copying the actions objects. This thread answers my question pretty well, with this post being the summary:


From my experience you can't really retain actions and get any benefit out of them.

There really isn't good way to reuse actions. If you find that you are deallocing too much that the game is unstable then you should forget actions and just schedule a method that does all the work.

Examples (All variables ending with an underscore are class variables "variablename_"):

BAD WAY TO RUN ACTIONS:

.... maybe in init
moveAction_ = [[MoveBy actionWithDuration:1.f position:ccp(100.f, 0.f)]retain];

.... Some other function
[sprite1_ runAction:moveAction_];
[sprite2_ runAction:moveAction_];

That example won't work because both sprite1_, sprite2_ let's say have the same position. They will definitely not move together! That is because the action is referenced by an actionManager and you just changed the target of that action.

Correct way:

.... maybe in init
moveAction_ = [[MoveBy actionWithDuration:1.f position:ccp(100.f, 0.f)]retain];

.... Some other function
[sprite1_ runAction:[[moveAction_ copy] autorelease]];
[sprite2_ runAction:[[moveAction_ copy] autorelease]];

Now the action will have the correct behavior but you've essentially lost all efficiency of doing a retain in the first place. You've pretty much created two new instantiations of the action.

The code above is exactly the same as:

[sprite1_ runAction:[MoveBy actionWithDuration:1.f position:ccp(100.f, 0.f)]];
[sprite2_ runAction:[MoveBy actionWithDuration:1.f position:ccp(100.f, 0.f)]];

So in the end you've gained no benefit of retaining the action. So why retain?

If you are really worried about the dealloc slowing down the game then the other way is to lose out on the convenience of actions and create your own scheduled action

...somewhere in init
[self schedule:@selector(moveStuff:)];

// do all you actions manually here
- (void) moveStuff:(ccTick) dt
{
   CGPoint delta = ccp(100.f,0.f);
   sprite1.position = ccp( (sprite1.position.x + delta.x * dt ), 
                           (sprite1.position.y + delta.y * dt ) );
}

So really it's up to you to decide between speed or convenience.

Kriem