Cocos2D iPhone — запуск действий по нескольким целям + обратный вызов

У меня есть массив объектов (objArray) и массив действий (actArray). Оба массива в порядке, я имею в виду, что объект с индексом 0 objArray должен выполнить действие 0 над actArray.

Чтобы пояснение было ясным, давайте представим, что оба массива имеют 3 объекта: obj0, obj1 и obj2.

obj0 has to perform action 0 on actArray
obj1 has to perform action 1 on actArray
obj2 has to perform action 2 on actArray

эти 3 операции (или n, в случае массива) должны выполняться одновременно.

Когда все анимации заканчиваются, мне нужно вызвать метод animationsFinished.

Как я могу это сделать?

Я начинаю на Кокосах. Я погуглил и не нашел ни одного практического примера. Я нашел CCSpan, но не понимаю, как это можно использовать с несколькими объектами, каждый из которых имеет свое собственное действие. Благодарю.


person Duck    schedule 07.02.2012    source источник
comment
Это опечатка, что вы хотите, чтобы действие 2 вызывалось на obj1? Это должно быть действие 1?   -  person eric.mitchell    schedule 07.02.2012


Ответы (3)


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

int yourAnimationDuration; //this needs to be set to whatever your animation speed is
for(int idx = 0; idx < 3; idx++) {
    [[objArray objectAtIndex:idx] runAction:[actArray objectAtIndex:idx]];
    [self performSelector:@selector(someMethodToBeExecutedWhenAnimationFinishes) withObject:nil afterDelay:yourAnimationDuration];
}

Или, если вы хотите, чтобы метод анимации был выполнен только один раз, просто удалите его из цикла for.

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

id finalAnimation = [CCSequence actionOne:[actArray objectAtIndex:idx] two:someMethod];

Это (я полагаю) выполнит ваш метод после завершения первого действия.

person eric.mitchell    schedule 07.02.2012
comment
Да, я думал о механизме обратного вызова, но я думаю, что это будет лучший вариант. Спасибо - person Duck; 07.02.2012
comment
Что касается performSelector: withObject: afterDelay: - этого лучше избегать, т.к. у cocos2d есть свой планировщик (с возможностью паузы/возобновления). - person brigadir; 07.02.2012

В приведенном выше случае вы упомянули, что someMethodToBeExecutedWhenAnimationFinishes будет выполняться три раза. Просто используйте его 1 раз после цикла. 'yourAnimationDuration' будет временем действия с максимальной продолжительностью, так как все остальные действия должны закончиться до действия с максимальной продолжительностью.

«CCSequence» — хороший вариант, но вам нужно выполнять CCSequence только с действием максимальной продолжительности, а не со всеми объектами.

Итак, в 1-м случае

int yourAnimationDuration; //this needs to be set to duration of action with maximum time
for(int idx = 0; idx < 3; idx++) {
    [[objArray objectAtIndex:idx] runAction:[actArray objectAtIndex:idx]];
}
 [self performSelector:@selector(someMethodToBeExecutedWhenAnimationFinishes) withObject:nil afterDelay:yourAnimationDuration];

Во 2-м случае Предположим, что ваше 2-е действие занимает максимальное время.

int actionNum = 2;
for(int idx = 0; idx < 3; idx++) {
   if(idx == (actionNum-1))
{
[[objArray objectAtIndex:idx] runAction:[CCSequence actions:[actArray objectAtIndex:idx],[CCCallFuncN actionWithTarget:self selector:@selector(someMethodToBeExecutedWhenAnimationFinishes:)],nil];
}
else{
 [[objArray objectAtIndex:idx] runAction:[actArray objectAtIndex:idx]];
}
}

Надеюсь, это поможет. Я не запускал этот код. Поэтому проверьте синтаксис, если он есть. :)

person Nikhil Aneja    schedule 08.02.2012

Этот код может понадобиться для запуска Multiple CCAction (каждое действие для другого CCNode/CCSprite/...); Но начиная Все по порядку !

CCMoveBy *moveUpAction = CCMoveBy::create(0.5,ccp(0,400));
CCMoveBy *moveRightAction = CCMoveBy::create(1,ccp(300,0));
CCMoveBy *moveDownAction = CCMoveBy::create(1,ccp(0,-400));

CCTargetedAction *mm = CCTargetedAction::create(someNode_1,moveUpAction);
CCTargetedAction *rr = CCTargetedAction::create(someNode_2,moveRightAction);
CCTargetedAction *dd = CCTargetedAction::create(someNode_3,moveDownAction);

// Here we first run 'moveUpAction' on someNode_1.
// After finishing that Action we start 'moveRightAction' on someNode_2
// After finishing the Action, we start ...
CCSequence *targetedSeq = CCSequence::create(mm,rr,dd,NULL);
whateverNode->runAction(targetedSeq );
person Emadpres    schedule 13.07.2014