cocos2d-x 之 帧动画管理类实现 配置 json 文件
我们做程序的目的要明确,程序员写出一段代码好与不好,通过比较就能体现出来。对于一些效果的调整,我们不需要自己修改代码,如果你想要动画播放的快一点,那么这些小活不应该是你去修改代码,而应该是由策划来完成,看看下面的代码吧!!!
Effect_Cfg_Data_Mgr.h
#ifndef EFFECT_CFG_DATA_MGR_H
#define EFFECT_CFG_DATA_MGR_H
#include "CocoStudio/Json/lib_json/json_lib.h"
#include "cocos2d.h"
USING_NS_CC;
class Effect_Cfg_Data_Mgr:public CCObject
{
public:
Effect_Cfg_Data_Mgr(void);
~Effect_Cfg_Data_Mgr(void);
static Effect_Cfg_Data_Mgr* instance();
int load_config(void);
int get_effect_cfg(const std::string& effect_id ,
std::string &effect_path,
float &duration_time,
float &scale,
float &x,
float &y,
float &delay_time );
int get_effect(CCSprite * effect_sprite, const std::string& effect_id);
CCAnimation* get_Animation(const std::string& effect_id);
void clean_effect(CCNode * effect);
int get_value_by_file( const char* file_name, CSJson::Value& data );
private:
CSJson::Value config_data_;
static Effect_Cfg_Data_Mgr* instance_;
};
#endif
Effect_Cfg_Data_Mgr.cpp
#include "Effect_Cfg_Data_Mgr.h"
#include "vector"
Effect_Cfg_Data_Mgr* Effect_Cfg_Data_Mgr::instance_ = 0;
Effect_Cfg_Data_Mgr::Effect_Cfg_Data_Mgr(void)
{
}
Effect_Cfg_Data_Mgr::~Effect_Cfg_Data_Mgr(void)
{
}
Effect_Cfg_Data_Mgr* Effect_Cfg_Data_Mgr::instance()
{
if( NULL == instance_ )
instance_ = new Effect_Cfg_Data_Mgr;
return instance_;
}
int Effect_Cfg_Data_Mgr::load_config(void){
CSJson::Value data;
get_value_by_file("game_data/effect_config.json", data);
config_data_ = data["effect_map"];
return 0;
}
int Effect_Cfg_Data_Mgr::get_effect_cfg(const std::string& effect_id ,
std::string &effect_path,
float &duration_time,
float &scale,
float &x,
float &y,
float &delay_time )
{
CSJson::Value& item_config = config_data_[effect_id];
if(item_config.isNull()){
return -1;
}
effect_path = item_config["path"].asCString();
duration_time = item_config["duration"].asFloat();
scale = item_config["scale"].asFloat();
x = item_config["pos_x"].asFloat();
y = item_config["pos_y"].asFloat();
delay_time = item_config["delay_time"].asFloat();
return 0;
}
int Effect_Cfg_Data_Mgr::get_effect( CCSprite * effect_sprite, const std::string& effect_id )
{
CCAnimation * animation = get_Animation(effect_id);
if(!animation){
return -1;
}
CSJson::Value& item_config = config_data_[effect_id];
float scale = item_config["scale"].asFloat();
float x = item_config["pos_x"].asFloat();
float y = item_config["pos_y"].asFloat();
float delay_time = item_config["delay_time"].asFloat();
bool loop = item_config["loop"].asInt()==1;
effect_sprite->setScale(scale);
effect_sprite->setPosition( ccp(x,y));
CCFiniteTimeAction* action;
if(loop){
action = CCRepeatForever::create( CCAnimate::create(animation) );
}
else{
effect_sprite->setVisible(false);
action = CCSequence::create
(
CCDelayTime::create(delay_time),
CCShow::create(),
CCAnimate::create(animation),
CCCallFuncN::create(this, callfuncN_selector(Effect_Cfg_Data_Mgr::clean_effect)),
NULL);
}
effect_sprite->runAction(action);
return 0;
}
CCAnimation* Effect_Cfg_Data_Mgr::get_Animation( const std::string& effect_id )
{
CSJson::Value& item_config = config_data_[effect_id];
if(item_config.isNull()){
return NULL;
}
CCAnimationCache* animationCache = CCAnimationCache::sharedAnimationCache();
CCAnimation * animation = animationCache->animationByName(effect_id.c_str());
if(animation){
return animation;
}
float duration_time = item_config["duration"].asFloat();
int count = item_config["count"].asInt();
std::string effect_path= item_config["path"].asCString();
char plist_file[80] = {0};
char item_name[80] = {0};
int pos = effect_path.find_first_of('/');
std::string file_name = effect_path.substr(pos+1);
sprintf(plist_file,("%s.%s"),effect_path.c_str(),"plist");
CCSpriteFrameCache* cache = CCSpriteFrameCache::sharedSpriteFrameCache();
cache->addSpriteFramesWithFile(plist_file);
CCArray* frame_array = CCArray::create();
for(int i = 1; i <= count; i++){
sprintf(item_name,("%s_%d.%s"),file_name.c_str(),i,"png");
CCSpriteFrame* f = cache->spriteFrameByName(item_name);
frame_array->addObject(f);
}
animation = CCAnimation::createWithSpriteFrames(frame_array, duration_time/count);
CCAnimationCache::sharedAnimationCache()->addAnimation(animation, effect_id.c_str());
frame_array->release();
return animation;
}
void Effect_Cfg_Data_Mgr::clean_effect( CCNode * effect )
{
effect->removeFromParentAndCleanup(true);
}
int Effect_Cfg_Data_Mgr::get_value_by_file( const char* file_name, CSJson::Value& data )
{
unsigned long size = 0;
unsigned char* pData = 0;
std::string path_name =
CCFileUtils::sharedFileUtils()->fullPathForFilename(file_name);
pData = cocos2d::CCFileUtils::sharedFileUtils()->getFileData
(file_name, "rb", &size);
CSJson::Reader reader;
if (!reader.parse((const char*) pData,(const char*) (pData+size), data))
{
CCLog("{ can not parse %s file: %d }", file_name,-1);
CC_SAFE_DELETE_ARRAY(pData);
return -1;
};
CC_SAFE_DELETE_ARRAY(pData);
return 0;
}
该类读取了一个效果的配置文件(game_data/effect_config.json),让我们进入这个效果文件中一窥其中的究竟吧……
这个文件需要你手动配置一下,如果你的英语还可以的话,不用我解释每个字段的意思了吧!!!
至于,表中配置的"path":"effect/xitong_shengfuyifen"这个路径所对应的信息呢,你只需要用 texturePaker 将你需要播放的帧动画打包就行了,然后放到 effect 路径下(当然这些路径信息,以及字段名称什么的都是你可以自己定义的)
使用方式:
Effect_Cfg_Data_Mgr::instance()->load_config(); //记住:在使用之前先加载文件信息
CCSprite *effect = CCSprite::create();
Effect_Cfg_Data_Mgr::instance()->get_effect(effect, "1000");
/*CCDirector::sharedDirector()->getRunningScene()*/
this->addChild(effect, 30);
运行效果截图:<实际效果需要你自己动手操作一下哦>
曾经有人跟我说过一句话:程序员是工具的创造者,而不是使用者。对,我们创造出来的工具就是让别人去使用的,正如上面的小例子,配表的工作就可以叫策划来弄了。想修改什么效果,直接修改表中对应的信息就行了!!!