在cocos2d中同步精灵动画

时间:2013-04-20 01:34:32

标签: cocos2d-iphone

我偶尔会在场景中添加一些脉动的精灵:

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];

我想让所有的精灵同步,我该怎么做呢?

2 个答案:

答案 0 :(得分:2)

嗯......不容易。我认为这样做的唯一方法是安排一个'flasherRamp',如下所示:

in .h

NSMutableArray *flashers;
<。> in .m,init method

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。 :从内存编码,未经测试,但应该接近。

答案 1 :(得分: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];
}

显然这并不完美,因为标志将由第一个精灵驱动以完成着色,但延迟应该可以忽略不计。如果你想确保它们都完成,只需将标志更改为精灵数量的运行计数,因此只要tintState等于batchnode中的精灵数量,就会调用“tinter”。