cocos2d-x中的序列帧动画实现可以用spritesheet来实现.什么是spritesheet呢?翻译过来就是精灵表单。它实际上是一张大的图片,在这张大的图片上包含了动画中每一帧的小图片。用spritesheet来实现动画除了需要这张大的图片外还需要一个plist格式的文件。这个文件的作用就是告诉我们每一帧对应的小图片在大的图片上的位置和其宽高信息。
为什么非要用spritesheet来实现动画呢?
原因是:
第一个原因:
如果不用spritesheet来实现动画的话,就只有把每一帧对应的小图片加载到内存中生成纹理对象。然后用纹理对象来创建精灵帧,然后用精灵帧来创建动画帧对象。最后生成动画数据对象。在这个过程中。如果每一帧对应的小图片的大小假设是480*320,那么cocos2d用这个图片来创建纹理对象时,它会把这个纹理的大小设置成512*512.为什么是512*512呢?因为cocos2d创建的纹理大小都是2的指数幂.这样的话就会有一部分纹理是空白区域。没有任何用处。如果这样的小图片很多的话。那么浪费的内存就非常大。
这就是第一个原因:浪费内存
第二个原因:
如果不用spritesheet来实现动画的话,就只有把一个一个的小图片加载到内存,OpenGL ES就要渲染很多次,有多少张小图片就要调用多少次OpenGL call。而spritesheet是把各个小的图片放在一张大的图片上。则只需要渲染一次。这样的话在最开始预加载资源的时候由于渲染速度慢,运行的速度就慢了下来。
这就是第二个原因:速度慢。
正是由于以上两个原因,所以用spritesheet来创建序列帧动画内存就相对小,运行速度相对就会更快。
要生成spritesheet对应的大图和plist文件,就要用到Texture Packer 或者 Zwoptex 这两个工具。
当然生成的spritesheet还可以进行优化,优化的是所占的内存大小。
关于如何用Texture Packer 或者 纹理像素格式(PixelFormat)对spritesheet进行优化请看这个博客:http://www.cnblogs.com/andyque/articles/1988097.html
直接上代码:
//把大的图片AnimBear.png和描述大图中小图的位置和宽高信息的文件plist数据加载到精灵帧缓冲区中。
CCSpriteFrameCache::sharedSpriteFrameCache()->addSpriteFramesWithFile("AnimBear.plist","AnimBear.png");
CCArray *pArray = CCArray::create();
for(int i=1; i<=8; ++i)
{
char buffer[50]= {0};
sprintf(buffer, "bear%d.png", i);
//生成精灵帧
CCSpriteFrame *pSpriteFrame = CCSpriteFrameCache::sharedSpriteFrameCache()->spriteFrameByName(buffer);
//生成动画帧
CCAnimationFrame *pAnimationFrame = new CCAnimationFrame();
pAnimationFrame->initWithSpriteFrame(pSpriteFrame, 0.5f,NULL);
pArray->addObject(pAnimationFrame);
}
//生成动画数据对象
CCAnimation *pAnimation = CCAnimation::create(pArray, 0.3f,1);
//生成动画动作对象
CCAnimate *pAnimate = CCAnimate::create(pAnimation);
CCRepeatForever *pRepeatForever = CCRepeatForever::create(pAnimate);
m_pBearSprite = CCSprite::create("CloseNormal.png");
CCSize size = CCDirector::sharedDirector()->getWinSize();
m_pBearSprite->setPosition(CCPointMake(size.width/2, size.height/2));
addChild(m_pBearSprite);
m_pBearSprite->runAction(pRepeatForever);
用Texture Packer生成大图是AnimBear.png 和对应的 AnimBear.plist