1. cocos2d-x播放帧动画需要图片帧集合的描述,以及动画的描述,前者可以直接通过flash自带的插件导出,如图所示
后者可以自己写一个脚本cocos2dxAni.jsfl,放置于形如C:\Program Files (x86)\Adobe\Adobe Flash CS6\Common\Configuration\Sprite Sheet Plugins 的目录下
// cocos2dxAni.jsfl
// export Cocos2d ani plist
// Ruoqian, Chen<piao.polar@gmail.com> 2013.9.22.
function getPluginInfo(lang)
{
// fl.trace("==== getPluginInfo");
// fl.trace(lang);
// fl.trace("---- getPluginInfo");
pluginInfo = new Object();
pluginInfo.id = "cocos2dxAni";
pluginInfo.name = "cocos2dx Ani";
pluginInfo.ext = "plist";
pluginInfo.encoding = "UTF8";
pluginInfo.capabilities = new Object();
pluginInfo.capabilities.canRotate = true;
pluginInfo.capabilities.canTrim = true;
pluginInfo.capabilities.premultipliedAlpha = true;
pluginInfo.capabilities.canShapePad = true;
pluginInfo.capabilities.canBorderPad = true;
pluginInfo.capabilities.canStackDuplicateFrames = true;
return pluginInfo;
}
function beginExport(meta)
{
// fl.trace("==== endExport");
// fl.trace(meta.app);
// fl.trace(meta.version);
// fl.trace(meta.image);
// fl.trace(meta.format);
// fl.trace(meta.size.w);
// fl.trace(meta.size.h);
// fl.trace(meta.scale);
// fl.trace("---- endExport");
var s = '<?xml version="1.0" encoding="UTF-8"?>\n';
s += '<!DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">\n';
s += '<plist version="1.0">\n';
s += '<dict>\n';
s += '\t<key>animations</key>\n';
s += '\t<dict>\n';
var fname = meta.image;
var ndx = meta.image.lastIndexOf('.');
if (ndx > 0)
{
fname = meta.image.substr(0, ndx);
}
s += '\t\t<key>' + fname + '</key>\n';
s += '\t\t<dict>\n';
s += '\t\t\t<key>delay</key>\n';
s += '\t\t\t<real>0.04</real>\n';
s += '\t\t\t<key>frames</key>\n';
s += '\t\t\t<array>\n';
return s;
}
function frameExport(frame)
{
// fl.trace("==== frameExport");
// fl.trace(frame.id);
// fl.trace(frame.frame.x);
// fl.trace(frame.frame.y);
// fl.trace(frame.frame.w);
// fl.trace(frame.frame.h);
// fl.trace(frame.offsetInSource.x);
// fl.trace(frame.offsetInSource.y);
// fl.trace(frame.sourceSize.w);
// fl.trace(frame.sourceSize.h);
// fl.trace(frame.rotated);
// fl.trace(frame.trimmed);
// fl.trace(frame.frameNumber);
// fl.trace(frame.symbolName);
// fl.trace(frame.frameLabel);
// fl.trace(frame.lastFrameLabel);
// fl.trace("---- frameExport");
var s ='\t\t\t\t<string>' + frame.id + '</string>\n';
return s;
}
function endExport(meta)
{
// fl.trace("==== endExport");
// fl.trace(meta.app);
// fl.trace(meta.version);
// fl.trace(meta.image);
// fl.trace(meta.format);
// fl.trace(meta.size.w);
// fl.trace(meta.size.h);
// fl.trace(meta.scale);
// fl.trace("---- endExport");
var s = '\t\t\t</array>\n';
s += '\t\t</dict>\n';
s += '\t</dict>\n';
s += '</dict>\n';
s += '</plist>\n';
return s;
}
然后一样的方式导出
2. 得到两个plist文件以后,很方便的就可以得到动画Node
// MyFlashNode.h
// Ruoqian, Chen<piao.polar@gmail.com>
// demo version 2013.10.16
#pragma once
#include "cocos2d.h"
USING_NS_CC;
class CMyFlashNode : public CCSprite
{
public:
static CMyFlashNode* create(const char *pszName, int nRepeat = 1, int nDelay_ms = 0);
virtual ~CMyFlashNode(void);
};
// MyFlashNode.cpp
// Ruoqian, Chen<piao.polar@gmail.com>
// demo version 2013.10.16
#include "MyFlashNode.h"
CMyFlashNode::~CMyFlashNode(void)
{
}
CMyFlashNode* CMyFlashNode::create( const char *pszName, int nRepeat /*= 1*/, int nDelay_ms /*= 0*/ )
{
CMyFlashNode* pSpriteAni = new CMyFlashNode;
pSpriteAni->autorelease();
pSpriteAni->init();
std::string strName = pszName;
std::string strPlist = strName + ".plist";
CCSpriteFrameCache::sharedSpriteFrameCache()->addSpriteFramesWithFile(strPlist.c_str());
std::string strPlistAni = strName + "_ani.plist";
CCAnimationCache::sharedAnimationCache()->addAnimationsWithFile(strPlistAni.c_str());
std::string strAni = strName + "_ani";
CCAnimation* pAni = CCAnimationCache::sharedAnimationCache()->animationByName(strAni.c_str());
std::string strFrame = strName + "0000";
CCSpriteFrame *pFrame = CCSpriteFrameCache::sharedSpriteFrameCache()->spriteFrameByName(strFrame.c_str());
pSpriteAni->setDisplayFrame(pFrame);
CCFiniteTimeAction* pActionWithRepeat = NULL;
switch (nRepeat) {
case 1:
pActionWithRepeat = CCAnimate::create(pAni);
break;
case -1:
//pActionWithRepeat = CCRepeatForever::create(CCAnimate::create(pAni));
pActionWithRepeat = CCRepeat::create(CCAnimate::create(pAni), UINT32_MAX);
break;
default:
pActionWithRepeat = CCRepeat::create(CCAnimate::create(pAni), nRepeat);
break;
}
CCSequence* pActionSeq = NULL;
float fDelay = nDelay_ms / 1000.0f;
CCCallFunc* pFuncAutoRemove = CCCallFunc::create(pSpriteAni, callfunc_selector(CCNode::removeFromParent));
if (fDelay > 0) {
pSpriteAni->setVisible(false);
pActionSeq = CCSequence::create(CCDelayTime::create(fDelay), CCShow::create(), pActionWithRepeat, pFuncAutoRemove, NULL);
} else {
pActionSeq = CCSequence::create(pActionWithRepeat, pFuncAutoRemove, NULL);
}
pSpriteAni->runAction(pActionSeq);
return pSpriteAni;
}
3. 实际调用也很简单,直接add即可
CMyFlashNode* pFlashNode = CMyFlashNode::create("star", 5, 3000);
this->setPosition(ptCenter);
this->addChild(pFlashNode);
由于支持配置循环播放次数和延时,且播放完成时候会自动释放,基本满足大部分情况的需要了。需要无限循环的话,repeat参数填写-1即可
因为是做示例,所以简单写了下,实际在项目中,我写成了一整套可配置形式的ui_element管理,会更灵活,以后有机会整理下再发上来。