Запускать частицу после выполнения действия

#objective-c #cocos2d-iphone #spritebuilder

#objective-c #cocos2d-iphone #spritebuilder

Вопрос:

Запускать частицу после последовательности перемещений

Часть кода 1

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

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

затем я хотел бы запустить этот код, подобный приведенному ниже.

Часть кода 2

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

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

Как я могу выполнить это утверждение после завершения выполнения действия: последовательность??

Ответ №1:

Используйте CCCallFunc , чтобы обернуть вызов функции в CCAction .

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

Вам нужно будет инкапсулировать «часть кода 2» в автономный метод с именем nextStep (или изменить определение действия, если вы предпочитаете использовать другое имя).

Надеюсь, это поможет.

Редактировать:

В cocos2d v3 вы можете использовать

 CCActionCallFunc
  

С аналогичным синтаксисом, или

 CCActionCallBlock
  

которую вы могли бы определить следующим образом:

 CCAction *nextStepAction = [CCActionCallBlock actionWithBlock:^{
    <code part2 here>
}];
  

Комментарии:

1. но это показывает ошибку, использование необъявленного идентификатора ‘CCCallFunc’ в моем cocos2d является версией 3.

2. Спасибо, я преуспел в использовании CCAllFunc!! Однако теперь я обнаружил новую проблему, я хотел бы передать аргумент в code part2.

3. Есть ли причина использовать CCActionCallBlock поверх CCCallBlock?

Ответ №2:

Я публикую решения как для Cocos2d, так и для Cocos2d-x, потому что все должны переключиться на cocos2d-x, потому что он компилируется как для iOS, так и для Android без дополнительного переноса, и на всякий случай, если кто-то, использующий Cocos2d-x, столкнется с этой же проблемой.

В Cocos2d-x я бы вызвал функцию из мета:

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

В Cocos2d я бы сделал это:

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

Если вы не хотите помещать это в функцию (как будто это просто одноразовое использование), следуя вашему стилю, вы должны быть в состоянии сделать это следующим образом:

 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];
  

Это будет работать последовательно. (Я немного не уверен в том, чтобы определять действие частицы отдельно, хотя есть несколько забавных моментов в определении материала, который вызывает другие объекты за пределами области видимости объекта).

Лично мне не нравится определять материал перед его вызовом, если я собираюсь вызвать его только один раз, я бы использовал CCSequence с такими действиями:

 [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
                   ]];
  

Комментарии:

1. Спасибо, ваше объяснение тоже хорошее, на данный момент я не планирую использовать cocos2d-x, однако оно должно быть хорошей ссылкой для пользователя cocos2d-x

2. в любом случае, только первый блок кода относится к 2d-x, последний блок кода должен работать именно в вашей ситуации.