2012-04-22 2 views
1

Я начал свое приложение, используя базовый код, найденный здесь, в menus tutorial. Таким образом, все мои «экраны» (их всего 5) реализованы как расширения класса CCLayer, и у меня есть общий + Scene Manager, который работает, добавляя мои классы слоев в качестве детей к новой сцене, а затем используя директора для запуска или замены воспроизводимой в данный момент сцены:cocos2d remove scene/scene transitions

+(void) goMenu{ 
    // \/---------- Issue right here, next line: 
    CCLayer *layer = [MenuLayer node]; 
    [SceneManager go: layer]; 
} 

+(void) go: (CCLayer *) layer{ 
    CCDirector *director = [CCDirector sharedDirector]; 
    CCScene *newScene = [SceneManager wrap:layer]; 
    if ([director runningScene]) { 
     [director replaceScene: newScene]; 
    }else { 
     [director runWithScene:newScene]; 
    } 
} 

+(CCScene *) wrap: (CCLayer *) layer{ 
    CCScene *newScene = [CCScene node]; 
    [newScene addChild: layer]; 
    return newScene; 
} 

Проблема, которую я испытываю, заключается в следующем. Предположим, у меня есть 2 слоя - «MenuLayer» и «GameLayer». Я начинаю с MenuLayer, а позже использую [SceneManager go:[GameLayer node]] для перехода на GameLayer. Из GameLayer, если я goMenu, приложение завершается с «NSInternalInconsistencyException», причина: «добавлен ребенок». Его нельзя добавить снова ', где указано. Я предположил, что это происходит, потому что я пытаюсь добавить некоторые дочерние спрайты в код инициализации слоя, и я снова их добавляю.

Моя первая попытка отладки заключалась в том, чтобы позвонить [self removeAllChildrenWithCleanup:YES]; в код onExit всех моих слоев. Это не решило проблему. Я добавил в некоторые журналы отладки и выяснил последнюю строку, которая выполняется до того, как сценарий взорвется, указан указанным [myLayerClass node];. Код инициализации внутри класса класса вообще не выполняется, поэтому он не может быть одним из добавленных спрайтов или других дочерних элементов, которые вызывают проблему. Опять же - помните, что все работает в первый раз, когда я пытаюсь открыть любую сцену. Он возвращается к открытой сцене, которая в настоящее время проблематична.

Так что я попробовал другой подход - подход, используемый в мире Cocos2D Hello. Я изменил все мои Слоя классы, добавив метод одноточечно + (идентификатор) сцена определяется следующим образом:

+(id) scene 
{ 
    CCScene *scene = [CCScene node];  
    myLayerClass *layer = [myLayerClass node]; 
    [scene addChild: layer]; 
    return scene; 
} 

Добавлено в [super dealloc] в dealloc и инкапсулированные все мои инициализации кода в:

-(id) init 
{ 
    if((self=[super init])) { 
     // All init code here.... 
    } 
} 

Конечно, все goLayerName одноэлементных методов в менеджере сцены было их содержимое заменено соответствовать этому - например:

+(void) goMenu { 
    //CCLayer *layer = [MenuLayer node]; 
    //[SceneManager go: layerMenu]; 
    CCDirector *director = [CCDirector sharedDirector]; 
    if ([director runningScene]) 
     [director replaceScene:[MenuLayer scene]]; 
    else 
     [director runWithScene:[MenuLayer scene]]; 
} 

I фигурном d это было так, как работает мир приветствия Cocos2D, это должно быть хорошо. Кроме того, поскольку каждая из моих сцен будет создаваться один раз и один раз (и, следовательно, каждый слой будет создан один раз и один раз). Никакого эффекта! В первый раз, когда я посещаю любую сцену, она работает так, как ожидалось. Всякий раз, когда я пытаюсь перейти к любой существующей сцене, я получаю ошибку, о которой я упоминал выше.

Я попытался провалить SO и found this, но я не уверен, как правильно его реализовать; также я не совсем уверен, что даже решит проблему - поскольку симптомы различны (он просто получает розовый экран, тогда как мое приложение завершается).

Любая помощь будет оценена по достоинству.

+0

fyi, когда я говорю «myLayerClass», это означает, что менюLayer, gameLayer, settingsLayer и т. Д. –

ответ

1

Для всех, кто был заинтересован в этом вопросе, я смог решить проблему.

Таким образом, любой ребенок ребенка, которого вы добавляете, не будет выпущен с releaseAllChildrenWithClenup. Эта функция освободит только детей, поэтому вы несете ответственность за выпуск любых вложенных детей.

В моей игре у меня были некоторые персонажи, и их глаза были вложены в головы спрайтов (чтобы я мог просто перемещать/вращать головы). У глаз был свой собственный цикл анимации, но я хотел, чтобы они трансформировались с головой.Все, что сработало, но так как у меня была строка кода в init, которая в основном [headSprite addChild:eyeSprite];, я должен был также добавить [headSprite removeChild:eyeSprite]; в код onExit, чтобы отделить его, последовалиreleaseAllChildrenWithClenup, чтобы удалить все дети уровня n = 1.

Как только это было обработано, все работало как рекламируемое.

Смежные вопросы