【问题标题】:How can I animate grass growing in Cocos2d?如何在 Cocos2d 中制作草的动画?
【发布时间】:2012-02-29 16:59:23
【问题描述】:

我正在尝试通过将相同的小精灵发芽 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 个动画。我希望每个丛(或丛集)在 3 秒的过程中均匀地为 1 个又一个动画。最重要的是在一个方向上设置动画,就像波浪效果一样,所以草开始从左到右或从下到上生长。

有没有更好的方法来生成 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,但 CPU 使用率从 20% 左右增加到 85%。主要的视觉缺陷是从前一场景过渡到这一场景的延迟。较小的设备无疑会遇到更多的延迟和帧速率下降。

我知道这可能不是处理此动画的正确方法。而且,我仍然想在它上面做一个滚动或波浪类型的动画,以便它在一个方向上传播。有人对这种效果有任何想法吗?

编辑 2:

这是根据 andrewx 的建议尝试的代码:

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

它的作用与我之前的代码相同,但避免了 sprite 批处理节点,这可能是件好事。我还没有测试性能,看看这是否是一种改进。

【问题讨论】:

    标签: xcode cocos2d-iphone ccsprite


    【解决方案1】:

    你可以画一个或几个单独的草叶,像这样随机选择它们:

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

    此示例假设您有 5 个不同的叶子可供随机选择,您可以在循环中进行迭代,将leaf 添加到您的父级,只要您想要草叶就可以。

    然后,单独或在同一个循环中,添加一个 CCMoveTo 以将叶子从下方向上推,使它们看起来正在生长。您也可以同时添加一个 CCScaleTo ,这样它们就可以同时进行。效果会很好。

    【讨论】:

    • 我不知道如何让这些精灵按顺序出现。这个我试过了,还是和上面一样的效果。我还没有测试性能比较。我根据您在我的问题中的建议发布了代码。
    • 你所说的“顺序”是什么意思?另外,我建议对所有事情都使用 arc4random,你有很多 random()。最后,我的建议也适用于批处理节点。
    • 对不起,顺序可能不是正确的词。如果我将延迟设置为 5 的持续时间,它会将我的 500 个精灵分成 5 组,并在动画完成后对一组接着一组进行动画处理。我希望它更加流畅,例如在第一个精灵通过其动画获得 10% 之后,第二个精灵开始等等。每个精灵上的交错动画可能是更好的措辞。就 random() 与 arc4random 而言,我迷路了。我一直在复制十几个不同的论坛和示例以使其正常工作,但我并不真正了解差异以及 () 之后的数字如何真正起作用。
    • 也许这是我想象的一个例子,由于大脑动画与程序动画的差异,代码无法完全匹配。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-03-18
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多