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

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

【cocos2d】注意!CCActionの使い回しはできません

同じアクションをいくつかのノードで走らせたい場合、同じCCActionオブジェクトを使い回したくなりませんか?
親子関係にあるノードを一緒にCCFadeOutでフェードアウトさせたい場合などです。

ところが、同じオブジェクトを使い回してこのようにプログラムすると_child1, _child2はフェードアウトしてくれません。一度runActionしてしまうとそのアクションオブジェクトは二度と使えないようですね。例えばこういう使い方をした場合です。

id fadeOut = [CCFadeOut actionWithDuration:0.5];
[self runAction:fadeOut];
[_child1 runAction:fadeOut];
[_child2 runAction:fadeOut];

こうすれば毎回フレッシュなオブジェクトが生成されますので意図した通りに動作します。

[self runAction:[CCFadeOut actionWithDuration:0.5];
[_child1 runAction:[CCFadeOut actionWithDuration:0.5];
[_child2 runAction:[CCFadeOut actionWithDuration:0.5];

同じオブジェクトに同じrunAction内で使い回す場合は何回でも同じオブジェクトを使用可能です。
これは、BeeClusterの1面のボス、クワガタの動作シーケンスです。同じアクションが何度も登場しているのがわかると思います。

    id moveDown = [CCMoveBy actionWithDuration:2.0 position:ccp(0, -300)];
    id openAndCloseJaw = [CCCallBlock actionWithBlock:^{
        [self openAndCloseJaw];
    }];
    id shootLaser = [CCCallBlock actionWithBlock:^{
        [self shootLaser];
    }];
    id shoot7Way = [CCCallBlock actionWithBlock:^{
        [self shoot7Way];
    }];
    id shootSlow = [CCCallBlock actionWithBlock:^{
        [self shootSlow];
    }];
    id shootFast = [CCCallBlock actionWithBlock:^{
        [self shootFast];
    }];
    id pause02 = [CCMoveBy actionWithDuration:0.2 position:CGPointZero];
    id moveLeft = [CCMoveBy actionWithDuration:1.0 position:ccp(-25, 0)];
    id moveRight = [CCMoveBy actionWithDuration:1.0 position:ccp(25, 0)];
    id sequenceL = [CCSequence actions: openAndCloseJaw, moveLeft, shootSlow, shootLaser, shootFast, shoot7Way,
                    pause02, shootSlow, shootLaser, moveLeft, nil];
    id sequenceR = [CCSequence actions: openAndCloseJaw, moveRight, shootSlow, shootLaser, shootFast, shoot7Way,
                    pause02, shootSlow, shootLaser, moveRight, nil];
    id sequenceLRL = [CCSequence actions:sequenceL, sequenceL, sequenceL, sequenceR, sequenceR, sequenceR, sequenceR, sequenceR, sequenceR,
                      sequenceL, sequenceL, sequenceL, nil];
    id repeat = [CCRepeat actionWithAction:sequenceLRL times:UINT_MAX];
    id sequence = [CCSequence actions: moveDown, repeat, nil];
    [self runAction:sequence];
}