木匣子

Web/Game/Programming/Life etc.

CCAnimate Loops

Cocos2d-x 提供了一组制作帧动画的工具:CCAnimationFrame + CCAnimation + CCAnimate.

CCAnimationFrame 是 CCSpriteFrame 的容器,但是增加了额外的帧信息,比如该帧的停留时间;

CCAnimation 是 CCAnimationFrame 的容器,包含的整个动画所需的帧序列。此外还有动画的循环次数,并且可以设置每帧之间的停留时间;

CCAnimate 是一个动作,它根据 CCAnimation 容器中的 CCAnimationFrame 以一定时间间隔切换 CCSprite 的外观(CCSpriteFrame)。并且从继承树看可以看到 CCAnimate -> CCActionInterval -> FiniteTimeAction -> CCAction 它是一个有限时长的动作。

可以把 CCAnimationFrame 想像成书中的页面,CCAnimation 想像成一本书,而 CCAnimate 就是翻书的动作。

注意事项

CCAnimate 是一个有限时长的动作,也就是说它总是会结束。但是昨天在 himi的cocos2d-x群 有开发者提出将 CCAnimate 置于序列动作 CCSequence 中时,后面的动作都无法执行。

我怀疑 CCAnimate 是否产生循环,但是作为一个有限时长的动作,不应该有循环的情况。后来对方检查了代码后说他给 CCAnimation 设置了 -1 的循环次数。

由于我电脑上只装了 Cocos2d-html5 所以我没看出 -1 能造成循环,唯一的副作用就是出现负数的动作时间。但是在 Cocos2d-x 中 m_uLoops 是一个 unsigned int 。

/** how many times the animation is going to loop. 0 means animation is not animated. 1, animation is executed one time, ... */
CC_SYNTHESIZE(unsigned int, m_uLoops, Loops)

于是 -1 就变成了 unsigned int 能表达的最大整数。这对一个有限时长的动作时间来说,真的是太长了……

正确的用法

不要使用负数的循环次数(官方应该在代码中有所限制,或者打印一些警告信息),这会使 Cocos2d-x 和 Cocos2d-html5 产生不一至的效果。

如果要使用循环帧动画,应该用 CCRepeatForever 来包装 CCAnimate 。

但是这里我产生一个疑惑,在 Cocos2d 的设计中 CCRepeatForever 居然也是继承至 -> CCActionInterval -> FiniteTimeAction 。这是一个哲学上的矛盾。