首页 数据库 mysql教程 spriter动画编辑器的cocos2d

spriter动画编辑器的cocos2d

Jun 07, 2016 pm 03:01 PM
c 动画 目前 编辑器

目前我的cocos2d-x编辑器的动画部分接口采用的是spriter动画编辑器提供的接口,spriter动画编辑器虽然简陋,但一般的需求基本上能够满足。可以在http://www.brashmonkey.com/spriter.htm下载,另外cocos2d-x的接口可以在论坛http://www.brashmonkey.com/foru

目前我的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;

}
	
登录后复制


本站声明
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn

热AI工具

Undresser.AI Undress

Undresser.AI Undress

人工智能驱动的应用程序,用于创建逼真的裸体照片

AI Clothes Remover

AI Clothes Remover

用于从照片中去除衣服的在线人工智能工具。

Undress AI Tool

Undress AI Tool

免费脱衣服图片

Clothoff.io

Clothoff.io

AI脱衣机

Video Face Swap

Video Face Swap

使用我们完全免费的人工智能换脸工具轻松在任何视频中换脸!

热工具

记事本++7.3.1

记事本++7.3.1

好用且免费的代码编辑器

SublimeText3汉化版

SublimeText3汉化版

中文版,非常好用

禅工作室 13.0.1

禅工作室 13.0.1

功能强大的PHP集成开发环境

Dreamweaver CS6

Dreamweaver CS6

视觉化网页开发工具

SublimeText3 Mac版

SublimeText3 Mac版

神级代码编辑软件(SublimeText3)

热门话题

Java教程
1662
14
CakePHP 教程
1419
52
Laravel 教程
1313
25
PHP教程
1262
29
C# 教程
1235
24
动画不工作在PowerPoint中[修复] 动画不工作在PowerPoint中[修复] Feb 19, 2024 am 11:12 AM

您是否正在尝试制作演示文稿,但无法添加动画?如果动画在你的WindowsPC上的PowerPoint中不起作用,那么这篇文章将会帮助你。这是一个常见的问题,许多人都在抱怨。例如,在Microsoft团队中演示或在屏幕录制期间,动画可能会停止工作。在本指南中,我们将探索各种故障排除技术,以帮助您修复在Windows上的PowerPoint中无法运行的动画。为什么我的PowerPoint动画不起作用?我们注意到可能导致Windows上PowerPoint中的动画无法工作问题的一些可能原因如下:由于个

VSCode和VS C++IntelliSense无法工作或拾取库 VSCode和VS C++IntelliSense无法工作或拾取库 Feb 29, 2024 pm 01:28 PM

VS代码和VisualStudioC++IntelliSense可能无法拾取库,尤其是在处理大型项目时。当我们将鼠标悬停在#Include&lt;wx/wx.h&gt;上时,我们看到了错误消息“CannotOpen源文件‘string.h’”(依赖于“wx/wx.h”),有时,自动完成功能无法响应。在这篇文章中,我们将看到如果VSCode和VSC++IntelliSense不能工作或不能提取库,你可以做些什么。为什么我的智能感知不能在C++中工作?处理大文件时,IntelliSense有时

C语言编程必备软件:五个推荐给初学者的好帮手 C语言编程必备软件:五个推荐给初学者的好帮手 Feb 20, 2024 pm 08:18 PM

C语言作为一门基础而重要的编程语言,对于初学者来说,选择合适的编程软件是非常重要的。在市场上有许多不同的C语言编程软件可供选择,但对于初学者来说,适合自己的选择可能有些困惑。本文将推荐给初学者的五个C语言编程软件,帮助他们快速入门和提高编程能力。Dev-C++Dev-C++是一款免费开源的集成开发环境(IDE),特别适合初学者使用。它简单易用,集成了编辑器、

修复Xbox错误代码8C230002 修复Xbox错误代码8C230002 Feb 27, 2024 pm 03:55 PM

您是否由于错误代码8C230002而无法在Xbox上购买或观看内容?一些用户在尝试购买或在其控制台上观看内容时不断收到此错误。抱歉,Xbox服务出现问题。稍后再试.有关此问题的帮助,请访问www.xbox.com/errorhelp。状态代码:8C230002这种错误代码通常是由于暂时的服务器或网络问题引起的。但是,还有可能是由于帐户的隐私设置或家长控制等其他原因,这些可能会阻止您购买或观看特定内容。修复Xbox错误代码8C230002如果您尝试在Xbox控制台上观看或购买内容时收到错误代码8C

跳票 2 年,国产 3D 动画电影《二郎神之深海蛟龙》定档 7 月 13 日 跳票 2 年,国产 3D 动画电影《二郎神之深海蛟龙》定档 7 月 13 日 Jan 26, 2024 am 09:42 AM

本站1月26日消息,国产3D动画电影《二郎神之深海蛟龙》发布一组最新剧照,正式宣布将于7月13日上映。据了解,《二郎神之深海蛟龙》是由迷狐星(北京)动漫有限公司、霍尔果斯众合千澄影业有限公司、浙江横店影业有限公司、浙江共赢影业有限公司、成都天火科技有限公司、华文映像(北京)影业有限公司出品,王君执导的动画电影,原定2022年7月22日在中国大陆上映。本站剧情简介:封神之战后,姜子牙携“封神榜”分封诸神,而后封神榜被天庭密封于九州秘境深海之下。事实上,除了分封神位,封神榜中还封缄着众多强大的妖邪元

ppt动画如何设置先进入再退出 ppt动画如何设置先进入再退出 Mar 20, 2024 am 09:30 AM

我们在日常的办公中经常会使用到ppt,那么你是否对ppt里边的每个操作功能都很了解呢?例如:ppt中怎么设置动画效果、怎么设置切换效果、每个动画的效果时长是多少?每个幻灯片能不能自动播放、ppt动画先进入再退出等等,那么今天这期我就先跟大家分享ppt动画先进入再退出的具体操作步骤,就在下方,小伙伴们快来看一看吧!1.首先,我们在电脑中打开ppt,单击文本框外侧选中文本框,(如下图红色圈出部分所示)。2.然后,单击菜单栏中的【动画】,选中【擦除】的效果,(如图红色圈出部分所示)。3.接下来,单击【

Go语言开发工具介绍:必备工具一览 Go语言开发工具介绍:必备工具一览 Mar 29, 2024 pm 01:06 PM

标题:Go语言开发工具介绍:必备工具一览在Go语言的开发过程中,使用合适的开发工具可以提高开发效率和代码质量。本文将介绍几款在Go语言开发中常用的必备工具,并附上具体的代码示例,让读者更加直观地了解它们的使用方法和作用。1.VisualStudioCodeVisualStudioCode是一款轻量级且功能强大的跨平台开发工具,具有丰富的插件和功能,

Golang编辑器推荐:五个适合开发的选择 Golang编辑器推荐:五个适合开发的选择 Jan 19, 2024 am 09:00 AM

随着Golang的流行和普及,越来越多的开发者开始使用这门编程语言。然而,和其他流行的编程语言一样,Golang的开发需要选择一款适合的编辑器来提高开发效率。在本文中,我们将介绍五个适合Golang开发的编辑器。VisualStudioCodeVisualStudioCode(简称VSCode)是微软开发的一款免费的跨平台编辑器。它是基于Elect

See all articles