Правильный перезапуск сцены cocos2d? - PullRequest
2 голосов
/ 27 января 2011

Как перезапустить сцену cocos2d и очистить память после предыдущей?

[director replaceScene:s] отображает розовый экран.Не могу заставить его работать.

Обход, который я сделал, приведен ниже, однако после закрытия сцены этот способ работает очень медленно и медленно реагирует на прикосновения. MainViewController.m :

- (IBAction)startScene { 

[CCTexture2D setDefaultAlphaPixelFormat:kTexture2DPixelFormat_RGBA8888];

if ([director runningScene]) {
    [director end];
    works = NO;
}
if (!works) {
    EAGLView *glview = [EAGLView viewWithFrame:CGRectMake(0,0, 768, 1024)]; 
    [self.view addSubview:glview];
    [director setOpenGLView:glview];
    CCLayer *layer = [PlayLayer node];
    CCScene *s = [CCScene node];
    [s addChild: layer];
    [director runWithScene:s];
}

}

Внутри PlayLayer.m Я возвращаюсь из сцены для просмотра, используя:

CCDirector *d = [CCDirector sharedDirector];
EAGLView *v = [d openGLView];
[v removeFromSuperview];

Приложение отображает изображения (1280x960x32, просмотр изображений внутри scrollview), и когда пользователь нажимает кнопку, он может запустить сцену cocos2d.Затем пользователь может уйти со сцены обратно для просмотра (.xib) и продолжить просмотр изображений, пока не найдет новое, с которого начинается сцена.

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

Ответы [ 3 ]

2 голосов
/ 08 марта 2011

Я, наконец, смог избавиться от розового экрана при замене сцены.Вот как я это делаю.При добавлении сцены я проверяю, запускается ли она в первый раз или в последующие разы.

MyTestAppDelegate * appDelegate = (MyTestAppDelegate *)[[UIApplication sharedApplication] delegate];
EAGLView *glView;
//check if scene is running first time then create OpenGLView, add to director and run the scene
if ([[CCDirector sharedDirector] runningScene] == NULL) {
    if( ! [CCDirector setDirectorType:kCCDirectorTypeDisplayLink] )
        [CCDirector setDirectorType:kCCDirectorTypeDefault];

    CCDirector *director = [CCDirector sharedDirector];
    glView = [EAGLView viewWithFrame:[appDelegate.window bounds]
                                   pixelFormat:kEAGLColorFormatRGB565   // kEAGLColorFormatRGBA8
                                   depthFormat:0                        // GL_DEPTH_COMPONENT16_OES
                        ];  
    [director setOpenGLView:glView];        
    [director setDeviceOrientation:kCCDeviceOrientationPortrait];   
    [director setAnimationInterval:1.0/60];
    [director setDisplayFPS:YES];
    [appDelegate.window addSubview:glView];     

    [[CCDirector sharedDirector] runWithScene: [MyScene node]];
}
//if scene is to be reloaded, add back the openGLView which was removed when removing the scene
else {      
    [appDelegate.window addSubview:[[CCDirector sharedDirector] openGLView]];
    [[CCDirector sharedDirector] replaceScene:[MyScene node]];
}

Для удаления текущей запущенной сцены:

[[CCDirector sharedDirector] replaceScene:[MySceneTwoLayer scene]];
[[CCDirector sharedDirector].openGLView removeFromSuperview];

Добавление MySceneTwoLayer необязательно.Это пустая сцена.Я использую его, чтобы убедиться, что предыдущая сцена была правильно удалена.И я проверил, правильно ли называется dealloc предыдущей сцены.

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

1 голос
/ 04 февраля 2013

Я столкнулся с подобной проблемой при использовании раскадровок и при возврате к исходному представлению пользовательского интерфейса, которое содержало мой CCGLView из другого представления.

//when leaving the scene containing the CCGLView.
[CCDirector director] popScene];

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

// in viewDidLoad
[CCDirector director] pushScene: theSceneIRemovedEtc];

Конечно, это может не сработать во всех случаях, но, безусловно, сработало для меня ..

0 голосов
/ 15 июля 2011

Хорошо, найдено решение, которое закрывает сцену изнутри и работает хорошо.

При запуске сцены я добавляю наблюдателя уведомлений в свой viewcontroller:

(...)
[director runWithScene:s];
[[NSNotificationCenter defaultCenter] addObserver:self 
      selector:@selector(mySceneEnd:) name:@"scene_ended" object:nil];

Это связано с:

- (void) mySceneEnd:(NSNotification *)notif {   
    if ([director runningScene])
        [director end];
    [[NSNotificationCenter defaultCenter] removeObserver:self];
}

Затем в методе окончания сцены я отправляю уведомление на свой viewcontroller:

EAGLView *v = [[CCDirector sharedDirector] openGLView];
[v removeFromSuperview];
[[NSNotificationCenter defaultCenter] postNotificationName:@"scene_ended" 
     object:nil userInfo:nil];

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

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