目前我的cocos2d-x编辑器的动画部分接口采用的是spriter动画编辑器提供的接口,spriter动画编辑器虽然简陋,但一般的需求基本上能够满足。可以在http://www.brashmonkey.com/spriter.htm下载,另外cocos2d-x的接口可以在论坛http://www.brashmonkey.com/forum/viewtopic.php?f=3&t=870下载。
接口导入进来之后,一切都很正常,然而在采用该接口进行开发时,发现有几个比较严重的问题。
问题1:资源采用多文件夹形式存储,渲染效率低
问题2:一个png只能有一个ccsprite,在编辑器是正常的,然而采用论坛那个接口导入到cocos2d-x就有问题。
问题3:精灵不能flip
问题4:不支持scale变换
陆续修改了上述4个问题
资源采用Sprite Frame实现
png的bug线性实现,时间复杂度O(1)
flip的实现参考cocos2d-x源码中CCTransitionFlipX的实现——摄像头换位
scale参考angle的变换就OK了
代码如下:
(代码中掺杂了编辑器部分的代码,精力有限,本代码仅供参考)
头文件:
//------------------------------------------------------------------------
//
// SCMLAnimator : KickStarter project Spriter renderer for cocos2d-x.
//
// Spriter website : http://www.kickstarter.com/projects/539087245/spriter
//
// Licensed under the BSD license, see LICENSE in root for details.
//
// Copyright (c) 2012 James Hui (a.k.a. Dr.Watson)
//
// For latest updates, please visit http://jameshui.com
//
//------------------------------------------------------------------------
#ifndef _CC_SPRITER_X_H_
#define _CC_SPRITER_X_H_
#include <vector>
#include <string>
#include "JEvent.h"
#include "cocos2d.h"
#include "TouchSprite.h"
#include "tinyxml.h"
class CCSpriterX;
#define FILE_SPRITE_SIZE 128
namespace SCMLHelper
{
struct File
{
File();
~File();
void Init(TiXmlNode *node);
int id;
std::string name;
float width;
float height;
//一个文件可能有多个关联
cocos2d::CCSprite* sprites[FILE_SPRITE_SIZE];
};
class Folder
{
public:
Folder();
~Folder();
void Init(TiXmlNode *node);
int GetFileCount();
File *GetFile(int index);
private:
int mId;
std::string mName;
std::vector <File *> mFiles;
};
struct ObjectRef
{
void Init(TiXmlNode *node);
int id;
int timeline;
int key;
int z_index;
};
struct Object
{
void Init(TiXmlNode *node, CCSpriterX *animator, int timelineId);
int folder;
int file;
float x;
float y;
float angle;
float scaleX;
float scaleY;
float pivot_x;
float pivot_y;
int z_index;
cocos2d::CCSprite *sprite;
};
class Key
{
public:
Key();
~Key();
void Init(TiXmlNode *node, CCSpriterX *animator, int timelineId);
int GetObjectRefCount();
ObjectRef *GetObjectRef(int index);
int GetObjectCount();
Object *GetObject(int index);
float GetTime();
bool IsSpinCounterClockwise();
private:
int mId;
float mTime;
bool mSpinCounterClockwise;
std::vector <Object *> mObjects;
std::vector <ObjectRef *> mObjectRefs;
// will have bones later
};
class Timeline
{
public:
Timeline();
~Timeline();
void Init(TiXmlNode *node, CCSpriterX *animator);
int GetKeyframeCount();
Key *GetKeyframe(int index);
private:
int mId;
std::vector <Key *> mKeyframes;
};
class Animation
{
public:
CC_SYNTHESIZE(JEvent *, event, Event);
CC_SYNTHESIZE(std::string, afterAction, AfterAction);
CCSpriterX * spr;
public:
void Restart();
Animation(CCSpriterX * spr);
~Animation();
void Update(float dt);
void Init(TiXmlNode *node, CCSpriterX *animator);
void Render();
bool IsDone();
public:
std::string getName(){return mName;}
private:
int mId;
std::string mName;
float mLength;
bool mLooping;
bool mDone;
Timeline *mMainline;
int mCurrKeyframe;
std::vector <Timeline *> mTimelines;
float mTimer;
cocos2d::CCPoint mPosition;
};
class Entity
{
private:
CCSpriterX * spr;
public:
Entity(CCSpriterX * spr);
~Entity();
void StartWithEvent(const char * name, JEvent * event);
std::string CurrentAction();
void Update(float dt);
void Render();
void Start(const char * name,const char* _afterAction);
void SetId(int id);
void SetName(const char *name);
void AddAnimation(Animation *animation);
void NextAnimation();
private:
int mId;
std::string mName;
std::vector <Animation *> mAnimations;
int mCurrAnimation;
};
}
class CCSpriterX : public TouchSprite
{
private:
struct Pit{
int fileId;
int id;
int folderId;
};
Pit fileSprites[FILE_SPRITE_SIZE];
CC_SYNTHESIZE(ccColor3B, colorX, ColorX);
public:
CCSpriterX();
~CCSpriterX();
virtual void setFlipX(bool bFlipX);
bool initWithFile(const char *filename);
std::string CurrentAction();
virtual void draw(void);
virtual void update(float dt);
static CCSpriterX * create(const char *filename);
cocos2d::CCSprite * getSprite(int folderId, int fileId, int timelineId);
void PlayNext();
void PlayWithEvent(const char * name, JEvent * event);
void Play(const char* name,const char* _afterAction = 0);
private:
std::vector <SCMLHelper::Folder *> mFolders;
std::vector <SCMLHelper::Entity *> mEntities;
int mCurrEntity;
};
#endif
源文件:
//------------------------------------------------------------------------
//
// CCSpriterX : KickStarter project Spriter renderer for cocos2d-x.
//
// Spriter website : http://www.kickstarter.com/projects/539087245/spriter
//
// Licensed under the BSD license, see LICENSE in root for details.
//
// Copyright (c) 2012 James Hui (a.k.a. Dr.Watson)
//
// For latest updates, please visit http://jameshui.com
//
//------------------------------------------------------------------------
#include "CCSpriterX.h"
#include "Common.h"
#include "jerror.h"
USING_NS_CC;
namespace SCMLHelper
{
///
File::File()
{
for(size_t i=0; i<FILE_SPRITE_SIZE; ++i){
sprites[i] = 0;
}
}
File::~File()
{
for(size_t i=0; i<FILE_SPRITE_SIZE; ++i){
if(sprites[i] != NULL){
sprites[i]->release();
}
}
}
void File::Init(TiXmlNode *node)
{
TiXmlElement *element = node->ToElement();
if (element)
{
int intValue;
float floatValue;
if (element->QueryIntAttribute("id", &intValue) == TIXML_SUCCESS)
id = intValue;
else
id = 0;
name = element->Attribute("name");
if (element->QueryFloatAttribute("width", &floatValue) == TIXML_SUCCESS)
width = floatValue;
else
width = 0;
if (element->QueryFloatAttribute("height", &floatValue) == TIXML_SUCCESS)
height = floatValue;
else
height = 0;
if (name.size()>0)
{
//资源全部放到scml目录中!
std::string path = workPath+gConfig->read<std::string>("res")+"/";
//sprite = CCSprite::create((path+"scml/"+name).c_str());
sprites[0] = CCSprite::createWithSpriteFrameName(name.c_str());
sprites[0]->retain();
}
}
}
///
Folder::Folder()
: mId(0)
{
mFiles.reserve(50);
}
Folder::~Folder()
{
int count = mFiles.size();
for (int i=0;i<count;i++)
CC_SAFE_DELETE(mFiles[i]);
mFiles.clear();
}
int Folder::GetFileCount()
{
return mFiles.size();
}
File *Folder::GetFile(int index)
{
if (index < (int)mFiles.size())
return mFiles[index];
return NULL;
}
void Folder::Init(TiXmlNode *node)
{
TiXmlElement *element = node->ToElement();
if (element)
{
int intValue;
if (element->QueryIntAttribute("id", &intValue) == TIXML_SUCCESS)
mId= intValue;
mName = element->Attribute("name")==0?".":element->Attribute("name");
for (TiXmlNode* fileNode = node->FirstChild(); fileNode; fileNode = fileNode->NextSibling())
{
File *file = new File();
file->Init(fileNode);
mFiles.push_back(file);
}
}
}
///
void ObjectRef::Init(TiXmlNode *node)
{
TiXmlElement *element = node->ToElement();
if (element)
{
int intValue;
if (element->QueryIntAttribute("id", &intValue) == TIXML_SUCCESS)
id = intValue;
else
id = 0;
if (element->QueryIntAttribute("timeline", &intValue) == TIXML_SUCCESS)
timeline = intValue;
else
timeline = 0;
if (element->QueryIntAttribute("key", &intValue) == TIXML_SUCCESS)
key = intValue;
else
key = 0;
if (element->QueryIntAttribute("z_index", &intValue) == TIXML_SUCCESS)
z_index = intValue;
else
z_index = 0;
}
}
///
void Object::Init(TiXmlNode *node, CCSpriterX *animator, int timelineId)
{
sprite = NULL;
float scaleFactor = CCDirector::sharedDirector()->getContentScaleFactor();
TiXmlElement *element = node->ToElement();
if (element)
{
int intValue;
float floatValue;
if (element->QueryIntAttribute("folder", &intValue) == TIXML_SUCCESS)
folder = intValue;
else
folder = 0;
if (element->QueryIntAttribute("file", &intValue) == TIXML_SUCCESS)
file = intValue;
else
file = 0;
if (element->QueryFloatAttribute("x", &floatValue) == TIXML_SUCCESS)
x = floatValue/scaleFactor;
else
x = 0;
if (element->QueryFloatAttribute("y", &floatValue) == TIXML_SUCCESS)
y = floatValue/scaleFactor;
else
y = 0;
if (element->QueryFloatAttribute("angle", &floatValue) == TIXML_SUCCESS)
angle = floatValue;
else
angle = 0;
if (element->QueryFloatAttribute("scale_x", &floatValue) == TIXML_SUCCESS)
scaleX = floatValue;
else
scaleX = 1;
if(scaleX < 1){
jlog("shit");
}
if (element->QueryFloatAttribute("scale_y", &floatValue) == TIXML_SUCCESS)
scaleY = floatValue;
else
scaleY = 1;
if (element->QueryFloatAttribute("pivot_x", &floatValue) == TIXML_SUCCESS)
pivot_x = floatValue;
else
pivot_x = 0;
if (element->QueryFloatAttribute("pivot_y", &floatValue) == TIXML_SUCCESS)
pivot_y = floatValue;
else
pivot_y = 1;
if (element->QueryIntAttribute("z_index", &intValue) == TIXML_SUCCESS)
z_index = intValue;
else
z_index = 0;
sprite = animator->getSprite(folder, file, timelineId);
}
}
///
Key::Key()
: mId(0)
, mTime(0)
, mSpinCounterClockwise(true)
{
mObjects.reserve(50);
mObjectRefs.reserve(50);
}
Key::~Key()
{
int count = mObjects.size();
for (int i=0;i<count;i++)
CC_SAFE_DELETE(mObjects[i]);
mObjects.clear();
count = mObjectRefs.size();
for (int i=0;i<count;i++)
CC_SAFE_DELETE(mObjectRefs[i]);
mObjectRefs.clear();
}
int Key::GetObjectRefCount()
{
return mObjectRefs.size();
}
ObjectRef *Key::GetObjectRef(int index)
{
if (index < (int)mObjectRefs.size())
return mObjectRefs[index];
return NULL;
}
int Key::GetObjectCount()
{
return mObjects.size();
}
Object *Key::GetObject(int index)
{
if (index < (int)mObjects.size())
return mObjects[index];
return NULL;
}
float Key::GetTime()
{
return mTime;
}
bool Key::IsSpinCounterClockwise()
{
return mSpinCounterClockwise;
}
void Key::Init(TiXmlNode *node, CCSpriterX *animator, int timelineId)
{
TiXmlElement *element = node->ToElement();
if (element)
{
int intValue;
float floatValue;
if (element->QueryIntAttribute("id", &intValue) == TIXML_SUCCESS)
mId = intValue;
float time = 0;
if (element->QueryFloatAttribute("time", &floatValue) == TIXML_SUCCESS) // was in milliseconds, convert to seconds instead
time = floatValue/1000.0f;
mTime = time;
if (element->QueryIntAttribute("spin", &intValue) == TIXML_SUCCESS)
mSpinCounterClockwise = !(intValue == -1);
for (TiXmlNode* objNode = node->FirstChild(); objNode; objNode = objNode->NextSibling())
{
element = objNode->ToElement();
const char *tabObj = element->Value();
if (strcmp(tabObj, "object_ref")==0)
{
ObjectRef *ref = new ObjectRef();
ref->Init(objNode);
mObjectRefs.push_back(ref);
}
else if (strcmp(tabObj, "object")==0)
{
Object *obj = new Object();
obj->Init(objNode, animator, timelineId);
mObjects.push_back(obj);
}
}
}
}
///
Timeline::Timeline()
: mId(0)
{
mKeyframes.reserve(50);
}
Timeline::~Timeline()
{
int count = mKeyframes.size();
for (int i=0;i<count;i++)
{
CC_SAFE_DELETE(mKeyframes[i]);
}
}
int Timeline::GetKeyframeCount()
{
return mKeyframes.size();
}
Key *Timeline::GetKeyframe(int index)
{
if (index < (int)mKeyframes.size())
{
return mKeyframes[index];
}
return NULL;
}
void Timeline::Init(TiXmlNode *node, CCSpriterX *animator)
{
int intValue;
TiXmlElement *element = node->ToElement();
if (element)
{
if (element->QueryIntAttribute("id", &intValue) == TIXML_SUCCESS)
mId = intValue;
for (TiXmlNode* keyNode = node->FirstChild(); keyNode; keyNode = keyNode->NextSibling())
{
element = keyNode->ToElement();
if (element)
{
Key *keyframe = new Key();
keyframe->Init(keyNode, animator, mId);
mKeyframes.push_back(keyframe);
}
}
}
}
///
Animation::Animation(CCSpriterX * _spr)
: mId(0)
, spr(_spr)
, mCurrKeyframe(0)
, mMainline(NULL)
, mDone(false)
, mTimer(0)
,event(0),afterAction("")
{
mTimelines.reserve(50);
}
Animation::~Animation()
{
int count = mTimelines.size();
for (int i=0;i<count;i++)
CC_SAFE_DELETE(mTimelines[i]);
mTimelines.clear();
}
void Animation::Init(TiXmlNode *node, CCSpriterX *animator)
{
int intValue;
float floatValue;
TiXmlElement *element = node->ToElement();
if (element)
{
if (element->QueryIntAttribute("id", &intValue) == TIXML_SUCCESS)
mId = intValue;
mName = element->Attribute("name");
if (element->QueryFloatAttribute("length", &floatValue) == TIXML_SUCCESS)
mLength = floatValue/1000.0f; // was in milliseconds, convert to seconds instead
const char *looping = element->Attribute("looping"); // was set to "false" in alpha, but in fact looping all the time
mLooping = true;
for (TiXmlNode* lineNode = node->FirstChild(); lineNode; lineNode = lineNode->NextSibling())
{
element = lineNode->ToElement();
const char *tabLine = element->Value();
if (strcmp(tabLine, "mainline")==0) // 1 mainline only
{
mMainline = new Timeline();
mMainline->Init(lineNode, animator);
}
else if (strcmp(tabLine, "timeline")==0)
{
Timeline *timeline = new Timeline();
timeline->Init(lineNode, animator);
mTimelines.push_back(timeline);
}
}
}
}
bool Animation::IsDone()
{
return mDone;
}
void Animation::Restart()
{
mDone = false;
mTimer = 0;
mCurrKeyframe = 0;
}
float lerp(float a, float b, float t){
return a+(b-a)*t;
}
void Animation::Update(float dt)
{
mTimer += dt;
if (mTimer >= mLength)
{
mDone = true;
Restart(); // always looping for now
}
int count = mMainline->GetKeyframeCount();
Key *keyframe = mMainline->GetKeyframe(mCurrKeyframe);
float currTime = keyframe->GetTime();
Key *keyframeNext = NULL;
int next = mCurrKeyframe+1;
if (next > count-1) // looping
next = 0;
keyframeNext = mMainline->GetKeyframe(next);
if (keyframeNext)
{
float nextTime = keyframeNext->GetTime();
if (next == 0)
nextTime = mLength;
if (mTimer >= nextTime)
{
mCurrKeyframe = next;
keyframe = keyframeNext;
currTime = keyframe->GetTime();
next = mCurrKeyframe+1;
if (next > count-1) // looping
next = 0;
keyframeNext = mMainline->GetKeyframe(next);
if (keyframeNext == NULL)
return;
nextTime = keyframeNext->GetTime();
if (next == 0)
nextTime = mLength;
}
float t = (mTimer-currTime)/(nextTime-currTime);
int count = keyframe->GetObjectRefCount();
for (int i=0;i<count;i++)
{
ObjectRef *ref = keyframe->GetObjectRef(i);
ObjectRef *refNext = keyframeNext->GetObjectRef(i);
if (ref && refNext)
{
Key *keyRef = mTimelines[ref->timeline]->GetKeyframe(ref->key);
Object *obj = keyRef->GetObject(0); // should be only 1 object
Key *keyRefNext = mTimelines[refNext->timeline]->GetKeyframe(refNext->key);
Object *objNext = keyRefNext->GetObject(0);
float x = lerp(obj->x, objNext->x, t);
float y = lerp(obj->y, objNext->y, t);
float scaleX = lerp(obj->scaleX, objNext->scaleX, t);
float scaleY = lerp(obj->scaleY, objNext->scaleY, t);
float angle = objNext->angle-obj->angle;
if (keyRef->IsSpinCounterClockwise())
{
if (angle < 0)
angle = (objNext->angle+360)-obj->angle;
}
else
{
if (angle > 0)
{
angle = (objNext->angle-360)-obj->angle;
}
}
if (ref->timeline != refNext->timeline)
t = 0;
angle = obj->angle+(angle)*t;
if (angle >= 360)
angle -= 360;
float px = obj->pivot_x+(objNext->pivot_x-obj->pivot_x)*t;
float py = obj->pivot_y+(objNext->pivot_y-obj->pivot_y)*t;
CCPoint newPos = ccp(x, y);
obj->sprite->setPosition(newPos);
obj->sprite->setRotation(-angle);
obj->sprite->setScaleX(scaleX);
obj->sprite->setScaleY(scaleY);
obj->sprite->setAnchorPoint(ccp(px, py));
}
}
}
}
void Animation::Render()
{
Key *keyframe = mMainline->GetKeyframe(mCurrKeyframe);
int count = keyframe->GetObjectRefCount();
for (int i=0;i<count;i++)
{
ObjectRef *ref = keyframe->GetObjectRef(i);
if (ref)
{
Key *keyRef = mTimelines[ref->timeline]->GetKeyframe(ref->key);
Object *obj = keyRef->GetObject(0); // should be only 1 object
obj->sprite->setColor(spr->getColorX());
obj->sprite->visit();
}
}
}
///
Entity::Entity(CCSpriterX * _spr)
: mCurrAnimation(0)
, mId(0)
, spr(_spr)
{
mAnimations.reserve(50);
};
Entity::~Entity()
{
int count = mAnimations.size();
for (int i=0;i<count;i++)
CC_SAFE_DELETE(mAnimations[i]);
mAnimations.clear();
}
void Entity::Update(float dt)
{
Animation *animation = mAnimations[mCurrAnimation];
animation->Update(dt);
}
std::string Entity::CurrentAction()
{
return mAnimations[mCurrAnimation]->getName();
}
void Entity::StartWithEvent(const char * name, JEvent * event)
{
for(size_t i=0; i<mAnimations.size(); ++i){
if(mAnimations[i]->getName() == std::string(name)){
mCurrAnimation = i;
mAnimations[i]->setEvent(event);
mAnimations[i]->Restart();
}
}
}
void Entity::Start(const char * name, const char * _afterAction)
{
for(size_t i=0; i<mAnimations.size(); ++i){
if(mAnimations[i]->getName() == std::string(name)){
mCurrAnimation = i;
mAnimations[i]->setAfterAction(_afterAction);
mAnimations[i]->Restart();
}
}
}
void Entity::Render()
{
Animation *animation = mAnimations[mCurrAnimation];
animation->Render();
}
void Entity::NextAnimation()
{
mCurrAnimation++;
if (mCurrAnimation >= (int)mAnimations.size())
mCurrAnimation = 0;
Animation *animation = mAnimations[mCurrAnimation];
animation->Restart();
}
void Entity::SetId(int id)
{
mId = id;
}
void Entity::SetName(const char *name)
{
mName = name;
}
void Entity::AddAnimation(Animation *animation)
{
mAnimations.push_back(animation);
}
}
///
using namespace SCMLHelper;
CCSpriterX::CCSpriterX()
{
mFolders.reserve(50);
mEntities.reserve(50);
for(int i=0; i<FILE_SPRITE_SIZE; ++i){
fileSprites[i].fileId = -1;
fileSprites[i].id = -1;
fileSprites[i].folderId = -1;
}
}
CCSpriterX::~CCSpriterX()
{
}
CCSpriterX *CCSpriterX::create(const char *filename)
{
CCSpriterX *animator = new CCSpriterX();
animator->type = SCML;
animator->m_state = kLivingStateUngrabbed;
if (animator && animator->initWithFile(filename))
{
//由于是动画层,没有大小,这里设置大小,使之能够拾取
animator->setContentSize(CCSizeMake(100, 100));
animator->autorelease();
return animator;
}
CC_SAFE_DELETE(animator);
return NULL;
}
void CCSpriterX::update(float dt)
{
if (dt > 0.0167f)
dt = 0.0167f;
Entity *entity = mEntities[mCurrEntity];
entity->Update(dt);
}
void CCSpriterX::draw(void)
{
Entity *entity = mEntities[mCurrEntity];
entity->Render();
}
std::string CCSpriterX::CurrentAction()
{
Entity *entity = mEntities[mCurrEntity];
return entity->CurrentAction();
}
void CCSpriterX::PlayWithEvent(const char * name, JEvent * event)
{
Entity *entity = mEntities[mCurrEntity];
entity->StartWithEvent(name, event);
}
void CCSpriterX::Play(const char* name, const char * _afterAction)
{
Entity *entity = mEntities[mCurrEntity];
entity->Start(name, _afterAction == 0?"":_afterAction);
}
void CCSpriterX::PlayNext()
{
Entity *entity = mEntities[mCurrEntity];
entity->NextAnimation();
}
CCSprite *CCSpriterX::getSprite(int folderId, int fileId, int timelineId)
{
if (folderId < (int)mFolders.size())
{
Folder *folder = mFolders[folderId];
if (folder)
{
File *file = folder->GetFile(fileId);
if (file){
int id = this->fileSprites[timelineId].id;
if(id == -1){
for(int i=0; i<FILE_SPRITE_SIZE; ++i){
if(fileSprites[i].fileId == fileId && fileSprites[i].folderId == folderId){
++id;
}
}
id += 1;
fileSprites[timelineId].folderId = folderId;
fileSprites[timelineId].fileId = fileId;
fileSprites[timelineId].id = id;
}
if(file->sprites[id] == 0){
file->sprites[id] = CCSprite::createWithSpriteFrameName(file->name.c_str());
file->sprites[id]->retain();
}
return file->sprites[id];
}
}
}
return NULL;
}
void CCSpriterX::setFlipX(bool bFlipX)
{
if(bFlipX != m_bFlipX){
float ex,ey,ez;
this->getCamera()->getEyeXYZ(&ex, &ey, &ez);
this->getCamera()->setEyeXYZ(ex, ey, bFlipX?-fabs(ez):fabs(ez));
this->m_bFlipX = bFlipX;
}
}
bool CCSpriterX::initWithFile(const char *filename)
{
char cfilename[256];
strcpy(cfilename, filename);
string name = strtok(cfilename, ".");
string suffix = strtok(cfilename, ".");
mCurrEntity = 0;
unsigned long filesize;
string path = workPath+gConfig->read<string>("res")+"/"+filename;
char *buffer = (char *)CCFileUtils::sharedFileUtils()->getFileData(path.c_str(), "rb", &filesize);
if (buffer == NULL)
return false;
//加载大图
string sfplist = workPath+gConfig->read<string>("res")+"/scml/"+name+".plist";
string sfpng = workPath+gConfig->read<string>("res")+"/scml/"+name+".png";
CCSpriteFrameCache::sharedSpriteFrameCache()->addSpriteFramesWithFile(sfplist.c_str(), sfpng.c_str());
TiXmlDocument doc;
doc.Parse(buffer);
TiXmlNode *root = doc.FirstChild("spriter_data");
if (root)
{
TiXmlElement *element = root->ToElement();
const char *version = element->Attribute("scml_version");
const char *generator = element->Attribute("generator");
const char *generatorVersion = element->Attribute("generator_version");
for (TiXmlNode* entityNode = root->FirstChild(); entityNode; entityNode = entityNode->NextSibling())
{
element = entityNode->ToElement();
if (element)
{
const char *tab = element->Value();
if (strcmp(tab, "folder")==0)
{
Folder *folder = new Folder();
folder->Init(entityNode);
mFolders.push_back(folder);
}
else if (strcmp(tab, "entity")==0)
{
int intValue;
Entity *entity = new Entity(this);
if (element->QueryIntAttribute("id", &intValue) == TIXML_SUCCESS)
entity->SetId(intValue);
entity->SetName(element->Attribute("name"));
for (TiXmlNode* animationNode = entityNode->FirstChild(); animationNode; animationNode = animationNode->NextSibling())
{
Animation *animation = new Animation(this);
animation->Init(animationNode, this);
entity->AddAnimation(animation);
}
mEntities.push_back(entity);
}
}
}
}
CC_SAFE_DELETE_ARRAY(buffer);
this->scheduleUpdate();
return true;
}