1

現在iPhoneでcocos2dとbox2dを使ったゲームを開発中です。
ゲーム コードの構成、ゲーム オブジェクトの構造などに関する記事をたくさん読みました。最初に、CCSprite から継承する基本クラス自体から継承することで、ゲーム オブジェクトの開発を開始しました。プレイヤーが操作できるすべてのゲーム アイテムを 1 回のドロー コールで描画する CCSpriteBatchNode がありました。私の Item クラスは CCSprite を間接的に継承しているので、簡単にアイテムを CCSpriteBatchNode に追加できました。さらに、cocos2d を使用してオブジェクトを保持することもできました。

記事を読んだ後、継承スタイルではなく、より構成指向のスタイルでコードをリファクタリングする必要があることを理解しました。そこで、NSObject から継承され、1 つ以上の CCSprite、1 つの b2Body などのプロパティを持つ GameObject 基本クラスを使用しました。

私が今直面している問題は、GameObject を CCSpriteBatchNode に直接追加できないことです。この問題は、GameObject のスプライト プロパティを CCSpriteBatchNode に追加することで簡単に解決できると最初に考えました。大丈夫ですが、 CCSprite を所有するオブジェクトを保持しているのは誰ですか? CCSprite から元のオブジェクトに簡単にアクセスするにはどうすればよいですか (userData/Object は問題ありません) ?

アイテムを保持する配列を作成する必要がありますか? このようなゲーム オブジェクト構造で CCSpriteBatchNode をどのように使用するのか知りたいですか?

未回答のスレッドがすでにあり、この件について本当に聞きたいです. 単純な答えではありませんが、さらに先に進むための要素がいくつかあります。

ありがとう。

4

1 に答える 1

3

個人的には、NSObject を cocos2d クラスの基本クラスとして使用することはお勧めしません。単純に、スケジューリングなどの cocos2d の便利な機能がいくつか失われ、メモリ管理に関して簡単に自分自身を撃つことができるからです。

必要なのは、シーンに 1 つまたは複数のスプライト バッチ ノードがあるセットアップです。それらをスプライトのレイヤーと見なすことができます。CCNode から派生した実際のゲーム オブジェクト (MVC コントローラーと見なす) は、どこにでも追加できますが、通常はシーンに直接追加できます。

scene
 + batch node 1
   + sprite 1
   + sprite 2
   + sprite n
 + batch node 2
   + sprite 1
   + sprite 2
   + sprite n
 + game node 1
 + game node 2
 + game node 3
 + game node n

各ゲーム ノードにはインスタンス変数として 1 つ以上のスプライトがありますが、それらはノードの子ではないことに注意してください。たとえば、ゲーム ノード 1 クラスは次のようになります。

game node 1 class
  CCSprite* sprite1;  // instance variable
  CCSprite* sprite2;  // instance variable

ここで、ゲーム ノード 1 とそのスプライトを初期化するときに、スプライトを適切なスプライト バッチ ノードに追加します。通常、シーンのスプライト バッチ プロパティにアクセスするには、シングルトンのようにシーンにアクセスします。

sprite1 = [CCSprite spriteWithSpriteFrameName:@"doodle.png"];
[[scene sharedScene].batchNode1 addChild:sprite1];
sprite2 = [CCSprite spriteWithSpriteFrameName:@"splash.png"];
[[scene sharedScene].batchNode2 addChild:sprite2];

スプライト バッチ ノードの子である限り、スプライトを保持する必要はないことに注意してください。addChild メソッドがそれを保持します。実際には、それを保持する配列に追加するだけです。また、「保持」についてまだ考えている場合は、ぜひARC を使用してください。

スプライト バッチでスプライトにアクセスする方法を理解する必要はありません。これはゲーム ノード クラスのインスタンス変数として利用できます。必要に応じて、プロパティとして他のクラスで公開することもできます。

ゲーム ノード クラスは、明らかに、スプライトのプロパティの配置やその他の変更を含む、すべてのオブジェクトのゲーム ロジックを実行します。ゲーム ノード クラスで注意する必要があるのは、バッチ ノードからスプライトを削除することだけです。そうしないと、リークが発生する可能性があります。これを行うには、クリーンアップ メソッドをオーバーライドします。

-(void) cleanup
{
    [sprite1 removeFromParentAndCleanup:YES];
    sprite1 = nil;
    [sprite2 removeFromParentAndCleanup:YES];
    sprite2 = nil;

    [super cleanup];
}

dealloc メソッドのコードを含め、クリーンアップ後に実行されるコードがある可能性があるため、変数を nil に設定することが重要です。また、dealloc でスプライトを削除することもできますが、設定によっては、ゲーム ノード クラスがまだ保持しているスプライトへの参照が原因で、dealloc が呼び出されない場合もあります。したがって、スプライトがゲーム ノード クラス自体の子 (または孫) でない場合は、クリーンアップ メソッドを使用する方が一般的に安全です。

于 2012-05-03T12:28:27.243 に答える