我使用menus tutorial中的基本代码启动了我的应用。以这种方式,我的所有'屏幕'(只有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'终止,原因:'child已经添加。如果需要,它不能再添加。我认为这种情况正在发生,因为我试图在图层的初始化代码中添加一些子精灵,然后我再次重新添加它们。
我首次尝试调试是在我所有图层的[self removeAllChildrenWithCleanup:YES];
代码中调用onExit
。这并没有解决问题。我添加了一些调试日志,发现在脚本爆炸之前执行的最后一行是指示的[myLayerClass node];
。层类中的初始化代码根本不会被执行 - 因此它不能是导致问题的精灵或其他子项之一。再次 - 请记住,我第一次尝试打开任何场景时一切正常。它正在回到一个目前存在问题的开放场景。
所以我尝试了一种不同的方法 - 在Cocos2D Hello世界中使用的方法。我修改了所有的Layer Classes,方法是添加一个如下定义的singleton +(id)场景方法:
+(id) scene
{
CCScene *scene = [CCScene node];
myLayerClass *layer = [myLayerClass node];
[scene addChild: layer];
return scene;
}
在dealloc的[super 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]];
}
我认为这是Cocos2D的hello world工作方式,它一定很好。此外,由于我的每个场景都会被创建一次并且只能创建一次(因此每个图层将被创建一次并且仅创建一次)。没有任何影响!我第一次访问它按预期运行的任何场景。每当我尝试导航回任何现有场景时,我都会收到上面提到的错误。
我试过围绕SO和found this,但我不确定如何正确实施它;我也不完全确定这会解决问题 - 因为症状不同(他只是得到一个粉红色的屏幕,而我的应用程序终止)。
任何帮助都将不胜感激。
答案 0 :(得分:1)
对于对这个问题感兴趣的人,我能够解决这个问题。
总之,您添加的孩子的任何孩子都不会与releaseAllChildrenWithClenup
一起发布。该函数只会释放直接的孩子,所以你有责任自己释放任何嵌套的孩子。
在我的游戏中,我有一些角色,他们的眼睛嵌在头部精灵中(这样我就可以移动/旋转头部)。眼睛有自己的动画循环,但我希望它们随着头部转换。所有这些都有效,但由于我在init中有一行基本上[headSprite addChild:eyeSprite];
的代码,我还必须在onExit代码中添加[headSprite removeChild:eyeSprite];
来解除它,跟随 by { {1}}删除所有n = 1级别的孩子。
一旦处理完毕,一切都按宣传的方式运作。