UIViewController освобождает мою сцену Cocos2d странным образом - PullRequest
1 голос
/ 07 октября 2011

У меня есть игровая сцена Cocos2d, которая загружается с EAGLView, загруженным UIViewController, но когда я выхожу из игровой сцены обратно в меню UIKit, моя игровая сцена странным образом освобождается. Я думаю, что если бы я сделал игру исключительно в Cocos2d, не комбинируя ее с UIKit, этого бы не случилось. Если при вызове UIViewController я вызываю pause в CCDirector, я обнаружил, что если я захочу снова войти в игровую сцену, UIViewController загрузится снова, и при простом возобновлении CCDirector отобразится пустой экран с ошибкой OpenGL. Если попытаться [[CCDirector sharedDirector] runWithScene], он говорит, что я не могу этого сделать, если сцена уже запущена, но если я пытаюсь заменить replaceScene, он говорит, что сообщение dealloc (для CCSprite, не знаю, какое именно) отправляется в освобожденный экземпляр. Вот часть моего кода:

- (void)viewDidLoad {
    [super viewDidLoad];
    glView = [EAGLView viewWithFrame:self.view.bounds
                         pixelFormat:kEAGLColorFormatRGB565 // kEAGLColorFormatRGBA8
                         depthFormat:0                        // GL_DEPTH_COMPONENT16_OES
              ];
    glView.autoresizingMask = UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight;
    [self.view insertSubview:glView atIndex:0];
    [[CCDirector sharedDirector] setOpenGLView:glView];

    if (![[CCDirector sharedDirector] runningScene]) {
        CCScene *scene = [GameLayer scene];
        [[CCDirector sharedDirector] runWithScene:scene];
    }
    else {
        [self.view insertSubview:[[CCDirector sharedDirector] openGLView] atIndex:0];
        [[CCDirector sharedDirector] resume];    // Pause is in viewWillDisappear

        // If I replace resume with below, I get message sent to deallocated instance
        [[CCDirector sharedDirector] replaceScene:scene];
    }
}

Если я запускаю его так, я получаю EXC_BAD_ACCESS внутри CCTextureAtlas в строке с glDrawElements(GL_TRIANGLES, (GLsizei) n*6, GL_UNSIGNED_SHORT, (GLvoid*)(start*6*sizeof(indices_[0])));

Если я запускаю его без повторной инициализации glview, а только при первой инициализации, например if (![[CCDirector sharedDirector]openGLView]) initialize, я получаю пустой экран и ошибку OpenGL 0x0506 в - [EAGLView swapBuffers].

Как бы мне сохранить свою сцену, не делая что-то слишком искаженное, или аккуратно освободить свою сцену, чтобы я мог перезагрузить ее с [[CCDirected sharedDirector] runWithScene]?

Ответы [ 2 ]

1 голос
/ 26 апреля 2012

Как бы вы ни покинули сен-вызов

[[CCDirector SharedDirector]end];

Это вызовет несколько методов для Директора и позволит вам без проблем вернуться на сцену.

1 голос
/ 08 октября 2011

Как вы «выходите из сцены»?Это был бы более интересный код для просмотра.

Вот что я нашел странным в коде, который вы разместили:

- (void)viewDidLoad {
    … 

    if (![[CCDirector sharedDirector] runningScene]) {
        ...
    }
    else {
        // Where does this scene variable come from?
        [[CCDirector sharedDirector] replaceScene:scene];
    }
}

Обычно, когда вы запускаете replaceScene, вы предоставляете новую сцену.Возможно, вы попытаетесь заменить сцену той же сценой, которая также является текущей запущенной сценой.Это, безусловно, приведет к краху cocos2d.Если вы хотите, чтобы та же сцена снова появлялась, не вызывайте replaceScene или не создавайте сцену заново.

Вы также захотите проверить, что текущая сцена не освобождается.Установите точку останова в методе dealloc сцены.Если это освобождает вас, вы, вероятно, впали в заблуждение, что вам нужно стереть сцену cocos2d из памяти.Вы не должны этого делать, я думаю, что cocos2d всегда ожидает, что после запуска runWithScene всегда будет хотя бы одна сцена бега.

Для чего бы вы ни захотели, вы захотите использовать startAnimation и stopAnimation вместо паузы и возобновления.Это полностью остановит Cocos2D без освобождения сцены, поэтому работает так же, как пауза / возобновление.Я предполагаю, что внутренне он полностью отключает игровой цикл, тогда как пауза / возобновление поддерживает очень медленную работу, то есть 4 кадра в секунду, если я правильно помню.

У меня были случаи, когда пауза / возобновление вызывало бы«Ошибка OpenGL 0x0506 in - [EAGLView swapBuffers]» и startAnimation / stopAnimation исправят это.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...