1

ときどき、脈動するスプライトを次のようにシーンに追加します。

CCSpriteBatchNode *batch = (CCSpriteBatchNode*) [scene getChildByTag: foo1];

sprite = [CCSprite spriteWithBatchNode:batch rect:CGRectMake(0, 0, 128, 128)];
sprite.position = foo2
CCTintTo *a = [CCTintTo actionWithDuration: .5 red:128 green: 128 blue: 128];
CCTintTo *b = [CCTintTo actionWithDuration: .5 red:255 green: 255 blue: 255];

[sprite runAction:[CCRepeatForever actionWithAction:
                   [CCSequence actionOne: a  two: b]]];

[batch addChild: sprite];

すべてのスプライトを同期して脈動させたいのですが、どうすればよいですか?

4

2 に答える 2

2

うーん...簡単ではありません。それを行う唯一の方法は、次のように「flasherRamp」をスケジュールすることです。

.h で

NSMutableArray *flashers;

in.m、init メソッド

flashers = [[NSMutableArray array] retain]; // choose your own ARC flavor, if you retain 
                                            // dont forget to release in dealloc

[self schedule:@selector(flasherRamp) interval:1.0f];

スプライトを作成する .m 内

foo2.visible=NO;
[flashers addObject foo2];

最後に

-(void) flasherRamp {
    for (CCSprite *flasher in flashers) {
        CCTintTo *a = [CCTintTo actionWithDuration: .5 red:128 green: 128 blue: 128];
        CCTintTo *b = [CCTintTo actionWithDuration: .5 red:255 green: 255 blue: 255];

        [flasher runAction:[CCRepeatForever actionWithAction:
               [CCSequence actionOne: a  two: b]]];
        flasher.visible=YES;
    }
    [flashers removeAllObjects];
}

ps。これがどれくらい続くかによっては、最終的に多少のドリフトが発生する可能性があります。

pps。ユーザビリティの観点から、これは、点滅するスプライトの出現と、トリガー イベントと実際の出現の間に最大 1 秒の遅延を引き起こす可能性のある「非同期」ゲーム イベントとの間に何らかの因果関係がある場合、良い考えではない可能性があります。フラッシャー。

ob cit。: メモリからコード化され、テストされていませんが、近いはずです。

于 2013-04-20T02:50:30.970 に答える
0

この場合、CCRepeatForever の使用は避けます。

現在の色合いの状態 (tintGray、tintWhite、tintDone) を定義する列挙型を作成し、状態をチェックするスケジュールされたセレクターを作成します。

状態が完了したら、アクションを繰り返しますが、バッチノードのすべての子に対して (それらが唯一の子であると仮定します)。

セレクターをスケジュールするには、init またはその他の読み込みメソッドに次を配置します。

// be sure to schedule the interval at a fast enough rate
[self schedule:@selector(tick:) interval:0.1f];

次に、メソッドを次のように定義します。

-(void)tick:(ccTime)dt
{
    if(tintState == tintDone)
    {
        [self unschedule:@selector(tick:)];
        [self tinter];
    }
}

次に、すべてのスプライトのティント アクションをスケジュールします。

-(void)tinter
{
    // could init and reuse this somewhere else to save on allocs
    CCSequence *actions = [CCSequence actions:
                       [CCCallBlockN actionWithBlock:^(CCNode* node)
                        {
                            tintState = tintGray;
                        }],
                       [CCTintTo actionWithDuration: .5 red:128 green: 128 blue: 128],
                       [CCCallBlockN actionWithBlock:^(CCNode* node)
                        {
                            tintState = tintWhite;
                        }],
                       [CCTintTo actionWithDuration: .5 red:255 green: 255 blue: 255],
                       [CCCallBlockN actionWithBlock:^(CCNode* node)
                        {
                            tintState = tintDone;
                        }],
                       nil];

    CCSpriteBatchNode *batch = (CCSpriteBatchNode*) [scene getChildByTag: foo1];
    for (CCSprite *flasher in batch.children) 
    {
        [flasher stopAllActions];
        [flasher runAction:actions];
    }

    // reschedule tick checking
    [self schedule:@selector(tick:) interval:0.1f];
}

明らかに、フラグは最初のスプライトによって駆動されて色付けが完了するため、これは完全ではありませんが、遅延は無視できるはずです。それらがすべて終了したことを確認したい場合は、フラグをスプライト数の実行中のカウントに変更するだけで、「tinter」は、tintState がバッチノード内のスプライト数と等しくなった場合にのみ呼び出されます。

于 2013-04-22T18:24:42.603 に答える