适当的cocos2d场景重启?

时间:2011-01-27 12:02:29

标签: objective-c cocos2d-iphone

如何在上一个场景之后重新启动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内的imageview),当用户按下按钮时,他可以启动cocos2d场景。然后,用户可以从场景返回到视图(.xib)并继续浏览图像,直到找到一个新的图像开始场景。

我相信这不是一个离开场景的好方法,但是我尝试的其他一切都会导致应用程序崩溃,或者我第二次开始拍摄粉红色屏幕。如何重新启动它?

3 个答案:

答案 0 :(得分:2)

我终于可以在替换场景时摆脱粉红色的屏幕。这就是我这样做的方式。在添加场景时,我会检查它是第一次运行还是后续运行。

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 :(得分:1)

在使用Storyboard时以及从另一个视图返回包含我的CCGLView的原始UI视图时,我遇到了一个类似的问题。

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

然后我在viewDIdLoad中注意到该视图控制器,它会在重新实例化时通过这个,然后你可以重新添加场景。

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

承认这可能不适用于所有情况,但肯定对我有用..

答案 2 :(得分:0)

好的,找到了一个从内部关闭场景并且运行良好的解决方案。

在开始场景时,我在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];

工作非常好,应用程序在关闭场景后快速运行,但这是一个古老的问题/答案,现在肯定有更好的方法。