Виділяють два способи створення анімації:
Для прикладу візьмемо анімацію свічки з безкоштовного паку. Там всього лише три кадри, їх дуже просто завантажити і використати ось таким чином:
Vector<SpriteFrame*> animFrames;
animFrames.reserve(3);
animFrames.pushBack(SpriteFrame::create("candle/SC300-1.png", Rect(0,0,64,64)));
animFrames.pushBack(SpriteFrame::create("candle/SC300-2.png", Rect(0,0,64,64)));
animFrames.pushBack(SpriteFrame::create("candle/SC300-3.png", Rect(0,0,64,64)));
// create the animation out of the frames
Animation* animation = Animation::createWithSpriteFrames(animFrames, 0.4f);
Animate* animate = Animate::create(animation);
// run it and repeat it forever
Sprite* candleSprite = Sprite::create();
candleSprite->runAction(RepeatForever::create(animate));
Тут цифри у Rect(0,0,64,64) такі, тому що файли розміром 64х64 пікселі.
Проблема в тому, що практика прямого завантаження файлів, яку ми досі використовували у всіх прикладах, насправді є досить поганою. Вона підходить для навчання, але краще буде використовувати списки файлів (sprite sheet).
У цьому місці я б дуже радив прочитати ось цю довгу, але дуже корисну статтю про анімацію. Якщо коротко, то є такий собі клас SpriteFrameCache, що може завантажувати зображення, описані у файлах *.plist. Такі файли можна створювати у різних програмах: непоганим варіантом є TexturePacker, також можна використовувати Shoebox, SpriteSheet Packer та Zwoptex. Результатом пакування є два файли:
Наприклад, можна взяти чотири зображення створіння у капюшоні, створити на його основі plist та ресурс і використати ось так:
SpriteFrameCache* sfc = SpriteFrameCache::getInstance();
const string violetMonsterFN = "littleCandleMonster/littleCandleMonster_violet.plist";
sfc->addSpriteFramesWithFile(violetMonsterFN);
Vector<SpriteFrame*> animFrames;
Animation *monsterAnimation = Animation::create();
char tmps[256];
for (int i = 1; i<=4; i++) {
sprintf(tmps, "lm-1-%i.png", i);
SpriteFrame * sf = sfc->getSpriteFrameByName(tmps);
monsterAnimation->addSpriteFrame(sf);
}
monsterAnimation->setDelayPerUnit(0.1);
Animate* animate = Animate::create(monsterAnimation);
Можна позбавитись від переліку імен файлів у коді, якщо використати метод addAnimationsWithFile класу AnimationCache. Тоді завантаження анімацій виглядатиме так:
const string plistFilename = "skeleton/skeleton_images.plist";
SpriteFrameCache::getInstance()->addSpriteFramesWithFile(plistFilename);
const string animationsPlistFN = "skeleton/skeleton_animations.plist";
AnimationCache::getInstance()->addAnimationsWithFile(animationsPlistFN);
А використання так:
Animation* animation = AnimationCache::getInstance()->getAnimation(idleAnimationName);
Animate* animate = Animate::create(animation);
skeletonSprite->runAction(animate);
Недоліком такого способу є те, що він вимагає якогось особливого plist-файлу. Цей файл відрізняється від тих, що створює Texture Packer (не зважаючи на однакове розширення) і його доводиться виписувати вручну. Для даного прикладу цей файл виглядатиме так.
У будь-якому разі, отримана в результаті акція animate може використовуватись так само, як і будь-яка інша акція. Ось, наприклад, фіолетове створіння пересувається подібно до зеленого НЛО з попередньої статті