Я пытаюсь заставить Cocos2D на iPhone «очистить себя», прежде чем я переключусь обратно на представление на основе UIView в своем приложении для iPhone, но оно перевыпускается (или I перевыпускается)что-то и происходит сбой, и я не могу сделать из этого ни головы, ни хвоста.
Это довольно долго, но я старался организовать это.
Моя иерархия узлов выглядит такэто и в скобках указано «что внутри» каждого узла:
CCScene
(меню) CCLayer
(символ) CCLayer
(Вся анимация) CCSprite, CCSpriteBatchNode
(Части анимации, может быть много каждого типа)
Итак, так как «Персонаж» запускает разные анимации, я удаляю «анимацию»"CCLayer из" персонажа "CCLayer, создайте новый" анимационный "CCLayer и добавьте его как дочерний элемент.Пока что никаких проблем не возникло.
Наконец, на CCScene есть кнопка, которая «заканчивает» часть приложения Cocos.Я хочу вернуться в UIKit-land, когда я нажимаю кнопку «Конец».
Однако, прежде чем я вернусь обратно в UIView-land, я хочу запустить одну заключительную анимацию для Персонажа, и когда ТО закончится., прекратить.Чтобы сделать это, я «регистрирую» обработчик на символе CCLayer следующим образом.Я вызываю «финальную» анимацию, а затем возвращаюсь к CCScene, когда финальная анимация завершена (с использованием KVO):
- (void) doEndWithHandler:(id<LWECharacterDelegate>)handler
{
// Handler is the CCScene, "self.parent" could work but I want it loosely coupled
self.endOfSessionHandler = handler;
// Tell character to start final animation -- this creates a new CCLayer,
// starts the animation, and assigns that CCLayer into self.animatedSequence
[self changeCharacterActionTo:END_ANIMATION key:nil]];
// The "animation" CCLayer has a property called "moving" -- observe it
[self.animatedSequence addObserver:self forKeyPath:@"moving" options:NSKeyValueObservingOptionNew context:NULL];
}
И затем мой код наблюдения, который вызывается обратно, когда «перемещение» становитсяNO
(= анимация заканчивается):
- (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context
{
if ([keyPath isEqualToString:@"moving"])
{
BOOL movingStatus = [[change objectForKey:NSKeyValueChangeNewKey] boolValue];
if (movingStatus == NO)
{
// Stop observing
[object removeObserver:self forKeyPath:@"moving"];
// Stop all animations on this level
[self.animatedSequence stopAnimation];
[self removeChild:self.animatedSequence cleanup:YES];
[self removeFromParentAndCleanup:YES];
// Handler callback
if (self.endOfSessionHandler && [self.endOfSessionHandler respondsToSelector:@selector(characterDidFinishSession)])
{
[self.endOfSessionHandler characterDidFinishSession];
}
}
} // if key = moving
}
Теперь вы можете сказать,
Не знал, что вы можете просто добавить обратный вызов, используя CCCallFunc в качестве действияна вашей анимации в конце, так что вы знаете, когда вы закончите двигаться?
Да, я знаю это - но дело в том, что CCScene "знает", когда нажимается кнопка завершения -- не какая-то конкретная анимация.CCAction уже находится в движении, когда нажата кнопка завершения, поэтому я хочу сообщить всем спрайтам ОСТАНОВИТЬ анимацию и уничтожить.
Мой анимационный CCLayer имеет некоторый специальный код, чтобы сообщить мне, когда спрайт (ы) остановилсяперемещение.Этот код работает хорошо - я использую обратный вызов CCCallFunc
в конце каждой анимации, чтобы сообщить моему классу "анимации" CCLayer, что это сделано.
Почему, похоже, проблема в том, чтоЯ получаю уведомление KVO о том, что «перемещение» изменилось, ДО того, как трассировка стека действий Cocos2D размоталась.Я почти уверен, что моя проблема где-то там, потому что, как только приходит уведомление KVO, я пытаюсь все остановить (см. Код выше).Однако не все останавливается, потому что инфраструктура Cocos2D дает сбой (перевыпуск), когда он пытается «обернуть» трассировку стека.
Разве невозможно остановить анимацию из обратного вызова CCCallFunc, который является анимацией действия?тот же спрайт?
Для вас, истинных кокосовых голов, точная линия сбоя:
if( currentTarget->currentActionSalvaged ) {
// The currentAction told the node to remove it. To prevent the action from
// accidentally deallocating itself before finishing its step, we retained
// it. Now that step is done, it's safe to release it.
[currentTarget->currentAction release];
.. которая находится в строке 327 CCActionManager.m
.