1

我使用菜单教程中的基本代码启动了我的应用程序。以这种方式,我所有的“屏幕”(只有 5 个)都作为 CCLayer 类的扩展来实现,并且我有一个共享的 + 场景管理器,它通过将我的图层类作为子类添加到新场景中来工作,然后使用导演运行或替换当前正在播放的场景:

+(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 world 中使用的方法。我通过添加如下定义的单例 +(id) 场景方法修改了所有图层类:

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

在dealloc中添加了一个[super dealloc],并将我所有的init代码封装在:

-(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]];
}

我想这就是 Cocos2D 的 hello world 的工作方式,它一定很好。此外,由于我的每个场景都将单独创建一次(因此每个图层都将单独创建一次)。一点效果都没有!我第一次访问任何场景时,它都会按预期运行。每当我尝试导航回任何现有场景时,都会收到上面提到的错误。

我试着在 SO 周围摸索,发现了这个,但我不确定如何正确实现它;我也不完全确定这是否能解决问题——因为症状不同(他只是得到一个粉红色的屏幕,而我的应用程序终止了)。

任何援助将不胜感激。

4

1 回答 1

1

对于任何对此问题感兴趣的人,我都能够解决这个问题。

总之,您添加的孩子的任何孩子都不会被释放releaseAllChildrenWithClenup。该函数只会释放直接子级,因此您有责任自己释放任何嵌套的子级。

在我的游戏中,我有一些角色,他们的眼睛嵌套在头部精灵中(这样我就可以移动/旋转头部)。眼睛有自己的动画循环,但我希望它们与头部一起变换。所有这些都奏效了,但由于我在 init 中有一行代码,基本上[headSprite addChild:eyeSprite];,我还必须添加[headSprite removeChild:eyeSprite];onExit 代码以将其分离,然后releaseAllChildrenWithClenup删除所有 n=1 级别的子级。

一旦处理完毕,一切都像宣传的那样工作。

于 2012-04-23T04:52:55.333 回答