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

私が抱えている問題は次のとおりです。「MenuLayer」と「GameLayer」の 2 つのレイヤーがあるとします。MenuLayer から始めて、後で GameLayer[SceneManager go:[GameLayer node]]に移行するために使用します。GameLayer から、goMenu すると、アプリは「NSInternalInconsistencyException」で終了します。理由: 「子は既に追加されています。再度追加することはできません」と示されています。レイヤーの初期化コードにいくつかの子スプライトを追加しようとしていて、それらを再度追加しているため、これが発生していると想定しました。

デバッグの最初の試みは、すべてのレイヤーのコード[self removeAllChildrenWithCleanup:YES];内で呼び出すことでした。onExitそれは問題を解決しませんでした。いくつかのデバッグ ログを追加したところ、スクリプトが失敗する前に実行された最後の行が指定された行であることがわかりました[myLayerClass node];。レイヤー クラス内の初期化コードはまったく実行されません。そのため、追加されたスプライトまたはその他の子の 1 つが問題を引き起こしている可能性はありません。繰り返しますが、最初にシーンを開こうとすると、すべてが機能することを思い出してください。現在問題のある開いているシーンに戻ります。

そこで、Cocos2D の Hello world で使用されている別のアプローチを試しました。次のように定義されたシングルトン +(id) シーン メソッドを追加して、すべてのレイヤー クラスを変更しました。

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

[super dealloc]deallocに aを追加し、すべての初期化コードを次の中にカプセル化しました。

-(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 の仕組みだと思いました。また、各シーンは 1 回だけ作成されるため (したがって、すべてのレイヤーは 1 回だけ作成されます)。何の効果もありません!初めてシーンにアクセスすると、期待どおりに実行されます。既存のシーンに戻ろうとすると、上記のエラーが表示されます。

SO をいじってみましたが、これを見つけましたが、適切に実装する方法がわかりません。また、問題が解決するかどうかも完全にはわかりません-症状が異なるためです(アプリが終了するのに、彼はピンクの画面になるだけです)。

任意の支援をいただければ幸いです。

4

1 に答える 1

1

この質問に興味を持った人のために、私は問題を解決することができました.

要約すると、追加した子の子は で解放されませんreleaseAllChildrenWithClenup。この関数は直接の子のみを解放するため、ネストされた子を自分で解放する必要があります。

私のゲームでは、何人かのキャラクターがいて、その目が頭のスプライトにネストされていました (頭を移動/回転させることができるようにするため)。目は独自のアニメーション ループを持っていましたが、頭と一緒に変形させたいと思いました。すべてうまくいきましたが、基本的に init にコード行があったため、 onExit コードを[headSprite addChild:eyeSprite];追加して関連付けを解除し、次にn=1 レベルの子もすべて削除する必要がありました。[headSprite removeChild:eyeSprite];releaseAllChildrenWithClenup

それが処理されると、すべてが宣伝どおりに機能しました。

于 2012-04-23T04:52:55.333 に答える