0

Trigger particle after move sequence

Code part1

CCActionMoveTo *moveTo = [CCActionMoveTo actionWithDuration:0.2f position:nextPosition];
CCActionRemove *remove = [CCActionRemove action];

CCActionSequence *sequence = [CCActionSequence actionWithArray:@[moveTo,remove]];
[mySprite runAction:sequence];

then I would like to fire this code like this below.

Code part2

CCParticleSystem *mergePart1 = (CCParticleSystem *)[CCBReader load:@"MergePart1"];
mergePart1.autoRemoveOnFinish = TRUE;

mergePart1.position = mySprite.position;
[game.parent addChild:mergePart1];

How can I exec this statement after runAction:sequence finished??

whitebear
  • 11,200
  • 24
  • 114
  • 237

2 Answers2

1

Use CCCallFunc to wrap a function call in a CCAction.

CCAction* nextStepAction = [CCCallFunc actionWithTarget:self selector:@selector(nextStep)];
CCActionSequence *sequence = [CCActionSequence actionWithArray:@[moveTo,remove, nextStepAction]];

You will need to encapsulate "code part 2" in a self-standing method called nextStep (or change the action definition if you prefer using a different name).

Hope this helps.

EDIT:

On cocos2d v3, you can use

CCActionCallFunc

With a similar syntax, or

CCActionCallBlock

which you could define like this:

CCAction *nextStepAction = [CCActionCallBlock actionWithBlock:^{
    <code part2 here>
}];
sergio
  • 68,819
  • 11
  • 102
  • 123
1

I'm posting solutions for both Cocos2d and Cocos2d-x, because everyone should switch to cocos2d-x because it compiles for both iOS and Android with no extra porting, and just in case someone using Cocos2d-x runs across this same issue.

In Cocos2d-x I would call the function from a meta:

Sequence::create(MoveTo::create(1.0, Point(100, 200))),
                 CallFunc::create([&](){HelloWorld::myFunction()},
                 null);

In Cocos2d I would do this:

[CCSequence actions:
   [CCMoveTo actionWithDuration:1.0 position:ccp(100, 100)],
   [CCCallFuncN actionWithTarget:self selector:@selector(myFunction:)],
   nil];

If you don't want to put it in a function (like it's just a one time use), following your style, you SHOULD be able to do it like this:

CCActionMoveTo *moveTo = [CCActionMoveTo actionWithDuration:0.2f position:nextPosition];
CCActionRemove *remove = [CCActionRemove action];
CCAction *particles = [CCCallBlock actionWithBlock:^{
    CCParticleSystem *mergePart1 = (CCParticleSystem *)[CCBReader load:@"MergePart1"];
    mergePart1.autoRemoveOnFinish = TRUE;
    mergePart1.position = mySprite.position;
    [game.parent addChild:mergePart1];
  }];


CCActionSequence *sequence = [CCActionSequence actionWithArray:@[moveTo,remove,particles]];
[mySprite runAction:sequence];

That will work in a sequence. (I'm a little uncertain about defining the particle action separately though, there's a few funny things about defining stuff that calls on other objects outside of the scope of the object).

Personally, I don't like to define stuff before I call it if I'm only going to call it once, I would use CCSequence with Actions like so:

[mysprite runaction:[CCSequence actions:
                     [CCMoveTo actionWithDuration:0.2f position:nextPosition],
                     [CCActionRemove action], //not sure what this does
                     [CCCallBlock actionWithBlock:^{
    CCParticleSystem *mergePart1 = (CCParticleSystem *)[CCBReader load:@"MergePart1"];
    mergePart1.autoRemoveOnFinish = TRUE;
    mergePart1.position = mySprite.position;
    [game.parent addChild:mergePart1];
                     }],
                     nil
                   ]];
redux
  • 1,157
  • 10
  • 21
  • THanks your explanation is also good, for now I am not planning to use cocos2d-x, however it must be the good reference for cocos2d-x user – whitebear Jul 06 '14 at 17:56
  • anyway, only the first code block pertains to 2d-x, the final code block should work in precisely your situation. – redux Jul 07 '14 at 21:25