Как я могу оживить рост травы в Cocos2d? - PullRequest
0 голосов
/ 29 февраля 2012

Я пытаюсь оживить поле травы, выращивая один и тот же маленький спрайт 500 раз.Эффект, который я пытаюсь достичь, заключается в том, что каждый отдельный пучок травы будет расти (в данном случае scaleY), и поле будет заполнено в течение 3 секунд.Я использую CCSpriteBatchNode, который сейчас читаю, это не эффективный способ использовать только один файл спрайта.Вот мой код, который дает мне желаемый эффект, но я не могу получить желаемую скорость.

    //GRASS batchNode
    CCSpriteBatchNode *grassBatch1 = [CCSpriteBatchNode batchNodeWithFile:@"grass1.png" capacity:500];
    grassBatch1.position = CGPointMake(0, -10);
    [self addChild:grassBatch1 z:1 tag:201];
    for (int x=0; x<500; x++) 
    {
        CCSprite *s = [CCSprite spriteWithBatchNode:grassBatch1 rect:CGRectMake(0, 0, 32, 32)];
        [s setOpacity:255];
        [grassBatch1 addChild:s];
        [s setPosition:ccp(arc4random()%1024-0, arc4random()%75-0)];
        [s setScaleY:0];
        [s setAnchorPoint:CGPointMake(0, 0)];
        CCScaleTo *grassScale = [CCScaleTo actionWithDuration:0.4 scale:1];
        CCEaseElasticOut *grassBounce = [CCEaseElasticOut actionWithAction:grassScale period:0.2f];
        CCDelayTime *grassDelay = [CCDelayTime actionWithDuration:random()%500];
        [s runAction:[CCSequence actions:grassDelay,grassBounce, nil]];
    }

В CCDelayTime число 500 заставляет анимировать каждый скопление по отдельности, но оно делает 1 скоплениев секунду.Если я сделаю это число 10, то оно объединит 500 сгустков в группы по 10 и оживит каждую группу 1 в секунду.Я хочу, чтобы каждый комок (или группа комков) анимировал 1 после другого, равномерно распределенного по времени в течение 3 секунд.Плюс ко всему этому будет анимация в направлении, подобном волновому эффекту, поэтому трава начинает расти слева направо или снизу вверх.

Существует ли лучший подход для создания 500 отдельно растущих спрайтов, использующих один и тот же файл .png?

РЕДАКТИРОВАТЬ:

ОК, так что я думаю, что мне нужно было лучше понять использование random ()% и целое число, которое следует.Я получаю, что 500 в продолжительности действительно увеличит анимацию до 500 секунд.Я хотел использовать меньше 1, а значения с десятичными знаками (например, 0,6) были отклонены.Фракции, видимо, работают.Чтобы приблизиться к тому, над чем я работаю, я внес следующие изменения в приведенный выше код:

Сначала я добавил случайное значение к действию масштаба:

CCScaleTo *grassScale = [CCScaleTo actionWithDuration:random()%7 scale:1];

, а затемиспользовал задержку на долю:

CCDelayTime *grassDelay = [CCDelayTime actionWithDuration:random()%1/20];

Я знаю, что этот путь для достижения эффекта, который я хочу, довольно обременителен для управления устройством.На iPad2 частота кадров падает с 60 до 48, а затем довольно быстро возвращается к 60, но загрузка процессора увеличивается с 20% или около того до 85%.Основным визуальным недостатком является задержка перехода от предыдущей сцены к этой.Меньшие устройства, несомненно, будут испытывать больше задержек и падений частоты кадров.

Я знаю, что это, вероятно, неправильный способ приблизиться к этой анимации.И я все еще хотел бы сделать анимацию по типу «вращение» или «волна», чтобы она проходила в одном направлении.У кого-нибудь есть мысли по поводу этого эффекта?

РЕДАКТИРОВАТЬ 2:

Это код, сделанный по предложению Эндрюкса:

    for (int i = 0; i < 500; i++) 
    {
        CCSprite *grassClump = [CCSprite spriteWithFile:@"grass1.png"];
        grassClump.anchorPoint = CGPointMake(0.5, 0);
        grassClump.position = ccp(arc4random()%1024-0, arc4random()%180-0);
        grassClump.scaleY = 0;
        CCScaleTo *grassScale = [CCScaleTo actionWithDuration:random()%7 scale:1];
        CCEaseElasticOut *easeGrassScale = [CCEaseElasticOut actionWithAction:grassScale period:0.3f];
        CCDelayTime *grassDelay = [CCDelayTime actionWithDuration:random()%5];
        [self addChild:grassClump z:5];
        [grassClump runAction:[CCSequence actions:grassDelay, easeGrassScale, nil]];
    }

Он действуетидентично моему предыдущему коду, но избегает узла спрайта, что, вероятно, хорошо.Я не проверял производительность, чтобы увидеть, если это улучшение или нет.

1 Ответ

1 голос
/ 01 марта 2012

Вы можете нарисовать один или несколько отдельных листьев травы, случайным образом выбрать их следующим образом:

CCSprite *leaf=[CCSprite spriteWithSpriteFrameName:[NSString stringWithFormat:@"grass%i.png",arc4random%5+1]];

В этом примере предполагается, что у вас есть 5 различных листьев для случайного выбора, и вы можете повторить это в цикле, добавив leaf к вашему родителю столько раз, сколько вы хотите листьев травы.

Затем, отдельно или в том же цикле, добавьте CCMoveTo, чтобы поднять листья снизу вверх, чтобы они выглядели растущими. Вы можете одновременно добавить CCScaleTo, чтобы они делали оба одновременно. Будет хороший эффект.

...