夏までにiPhone アプリつくってみっか!

趣味でiPhone/Androidアプリを開発し、日々勉強した事を書いています。オープンワールド系レースゲームをUnityで開発中です。

【cocos2d】プログラム実行中にzオーダーを変更して表示順序を変える

cocos2dでaddChildするときにzパラメーターを指定するとスプライトの表示順序を思い通りにコントロールする事ができます。
zの値が大きいほど上に表示され、重なったときにz値が小さいスプライトを覆い隠します。
BeeClusterの6面の蜂の巣のシーンではzパラメーターを細かく調整する事で蜂の巣の各レイヤーを重ね合わせ、その間に幼虫を表示しています。
これにより、まるで蜂の巣のなかに幼虫がいるように見えます。
詳細はこちらのポストをご参照ください。

ただし、幼虫が巣から出たあと再び巣の方に戻ると巣の中に隠れて見えなくなってしまいます。
敵が見えなくなるのは問題なので、一度巣から出たあとは常に巣の上に重なるようにしたいです。
cocos2dで実行中にzオーダーを変えるにはreorderChildメソッドを使用します。
zオーダーを変えたいスプライトの親のノードに対してメッセージを送ります。
例えばselfの表示プライオリティを変えたい場合は、
[self.parent reorderChild:self z:0];
とします。
BeeClusterではこのように使っています。

- (void) larvaMove
{
    _blinking = NO;
    float speed = MYRAND(100, 200);
    float distanceToTouch = 80.0;
    CGPoint touch = ccpAdd([TouchLayer sharedTouch].location, TOUCH_OFFSET); //狙う場所はタッチ位置の少し上
    CGPoint vector = ccpSub(touch, _target.position);
    if (ccpLength(vector) != 0) {
        vector = ccpMult(ccpNormalize(vector), distanceToTouch);
    }
    id toTouch = [CCMoveBy actionWithDuration:distanceToTouch/speed position:vector];
    id shoot = [CCCallBlock actionWithBlock:^{
        float difficulty = [DifficultyManager sharedDifficulty].difficulty;
        if (MYRAND(0, 6) <= difficulty) {
            [self shootFast];
        }
    }];
    id reorder = [CCCallBlock actionWithBlock:^ {
        [self.parent reorderChild:self z:0];
    }];
    [_target runAction:[CCSequence actions:toTouch, shoot, reorder, nil]];
}

CCMoveByで80ピクセル移動して巣から出た頃を見計らってzの値を変えています。
1連のアクションが終了するたびにこのメソッドが呼ばれるので無駄に何度もreorderChildが呼ばれることになりますが、特に副作用はないので気にしてはいません。処理速度に影響するほどの頻度では呼ばれませんので。
f:id:takujidev:20130611202703p:plain
このように巣とその上の岩の部分より上に幼虫が表示されるようになりました。