2012年9月12日水曜日

cocos2d: CCARRAY_FOREACHを使ってCCNodeを走査する

cocos2dでは、CCNodeを継承したCCLayerやCCSpriteを使って、画面を構成していきます。
今回は、CCARRAY_FOREACHを使って、CCNode(CCLayer)階層にある、特定のスプライトクラスにアクセスする方法を解説します。

あまり頻繁には使いませんが、使い方を知っておくと、便利なこともあると思います。


問題

ここにCCSpriteから派生したクラス、SpriteAクラスがある。
シーンにある全てのSpriteAインスタンスを非表示にせよ。

解決策

まず、以下の様な関数を用意しておきます。
再帰関数になっています。
- (void)searchNode:(CCNode*)node visible:(BOOL)vflag
{
    if ([node isKindOfClass:[SpriteA class]]) {
        node.visible = vflag;
    }
    
    CCNode *child;
    CCARRAY_FOREACH([node children], child) {
        [self searchNode:child visible:vflag];
    }
}

[node isKindOfClass:[SpriteA class]]は、nodeがSpriteAクラスを継承したクラスかどうか調べます。
継承しているのならYESが返るので、node.visibleに引数のvflagを代入します。

全てのCCNodeは、子を持っているかもしれないので、自身の子に対しても上記と同じ処理をしてやります。
こういう時、再帰処理が役に立ちます。

CCARRAY_FOREACHは、第1引数に与えた配列の中身を一つづつ第2引数に読み出し、{ }内を繰り返し処理するものです。

そこで、[node children]を使い、nodeが持つ子の配列をCCARRAY_FOREACHに渡してやります。
CCARRAY_FOREACHの{ }内では、再度searchNode関数を呼び出しています。こういう関数の中で、同じ関数を呼び出すことを再帰呼び出しと言います。

これによって、子が無くなるまで、階層深く走査することができます。

問題のSpriteAクラスを非表示にするには、以下のようにしてシーン階層トップのCCLayer(CCNode)を引き渡してやります。
CCLayer *layer = 〜 // 捜査するCCNode
[self searchNode:layer visible:NO];

また以下のようにすれば、再度表示されます。
[self searchNode:layer visible:YES];

関連記事

0 件のコメント:

コメントを投稿

Related Posts Plugin for WordPress, Blogger...