一个类似jsonreader的c++实现

本文探讨了游戏开发领域中AI音视频处理的应用,包括图像处理、AR特效、音视频直播流媒体等内容,展示了如何将这些技术应用于游戏场景,提升用户体验。
.h
template<class RT>
class cast_val;

class HelloResource {
	template<class T> friend class cast_val;
protected:	
	HelloResource(){

	}
	HelloResource(const std::string& key):key_prefix(key){
	}
public:
	typedef std::unordered_map<std::string,std::string> resource_object_item;
	~HelloResource(){

	}
public:
	static HelloResource* instance();
public:
	inline bool operator!()const{
		typedef resource_object_item::const_reference resource_item;
		return object_items.end() == std::find_if(object_items.begin(),object_items.end(),[this](resource_item it){
			return strncmp(this->key_prefix.c_str(),it.first.c_str(),this->key_prefix.length()) == 0;
		});
	}
	template<class T>
	inline void set(const std::string& key,const T& val){
		std::stringstream ss;
		ss << val;
		std::string dst(ss.str());
		object_items[key_prefix + key] = dst;
		if(key.find("score.max.value") != std::string::npos){
			update(key,dst);
		}
	}
public:
	template<class T>
	T cast(const std::string& key)const{
		cast_val<T> castor(*this);
		return castor(key);
	}
	template<class T,class Fn>
	const HelloResource& on(const std::string& key,Fn f)const{
		T val = cast<T>(key);
		f(val);
		return *this;
	}

	template<class Fn>
	const HelloResource& for_each(const std::string& key,Fn f)const{
		for(int i = 0; ; ++i){
			std::stringstream ss;
			ss << key_prefix <<  key << "[" << i << "].";
			HelloResource item(ss.str());
			if(!item){
				break;
			}
			f(item);
		}
		return *this;
	}
protected:
	void update(const std::string&key, const std::string& val);
	const std::string& get_value(const std::string& key)const{
		static std::string null_str;
		const std::string real_key = key_prefix + key;
        auto it = object_items.find(real_key);
        return (it == object_items.end()) ? null_str : it->second;
	}
protected:
	std::string key_prefix;
private:
	static resource_object_item& object_items;
	static resource_object_item& score_items;
};


template<>
class cast_val<unsigned int>{
public:
	cast_val<unsigned int>(const HelloResource& h):hr(h){

	}
	unsigned int operator()(const std::string& key){
		unsigned int ret = 0;
		std::stringstream ss;
		ss << std::hex << hr.get_value(key);
		ss >>  ret;
		return ret;
	}
protected:
	const HelloResource& hr;
};

template<>
class cast_val<int>{
public:
    cast_val<int>(const HelloResource& h):hr(h){
        
    }
    int operator()(const std::string& key){
    	int ret = 0;
        std::stringstream ss;
       	ss << hr.get_value(key);
        ss >> ret;
        return ret;
    }
protected:
    const HelloResource& hr;
};

template<>
class cast_val<std::string>{
public:
    cast_val<std::string>(const HelloResource& h):hr(h){
        
    }
    const std::string& operator()(const std::string& key){
        return hr.get_value(key);
    }
protected:
    const HelloResource& hr;
};

template<>
class cast_val<HelloResource>{
public:
    cast_val<HelloResource>(const HelloResource& h):hr(h){
        
    }
    HelloResource operator()(const std::string& key){
		return HelloResource(hr.key_prefix + key + ".");
    }
protected:
    const HelloResource& hr;
};

.cpp

 namespace {
 template<class Fn>
 void for_each_line(const std::string& f_name, Fn func) {
	std::string fullPath = CCFileUtils::sharedFileUtils()->fullPathForFilename(f_name.c_str());
	unsigned long nSize = 0,offset = 0;
	unsigned char* pBuffer = CCFileUtils::sharedFileUtils()->getFileData(fullPath.c_str(), "rb", &nSize);

 	if (NULL == pBuffer || 0 == nSize) {
 		free(pBuffer);
 		CCLOG("open file %s failed: %s(%d)",fullPath.c_str(),strerror(errno),errno);
 		return;
 	}
 	std::stringstream ss((char*)pBuffer);
 	for (;!ss.eof();) {
 		char line[1024] = {0};
 		ss.getline(line,sizeof(line));
 		if (0 == strlen(line) || line[0] == ';')
 			continue;
 		func(line);
 	}
 	free(pBuffer);
 }

 HelloResource::resource_object_item items;
 HelloResource::resource_object_item scores;

 void load_items(){
	for_each_line("main_menu.ini",[](const std::string& line){
		char key[128] = {0},val[256] = {0};
		sscanf(line.c_str(),"%[^=]=%[^\n]",key,val);
		items[key] = val;
		if(line.find(".score.max.value") != std::string::npos){
			scores[key] = val;
		}
	});
 }
 void load_scroes(){
	for_each_line("score.ini",[](const std::string& line){
		std::stringstream ss(line);
		std::string key,val;
		ss >> key >> val;
		items[key] = val;
		scores[key] = val;
	});
	std::string scoreFile = CCFileUtils::sharedFileUtils()->getWritablePath() + "score.ini" ;
	for_each_line(scoreFile,[](const std::string& line){
		std::stringstream ss(line);
		std::string key,val;
		ss >> key >> val;
		items[key] = val;
		scores[key] = val;
	});		
 }
 void update_scores(){
	std::string scoreFile = CCFileUtils::sharedFileUtils()->getWritablePath() + "score.ini" ;
	std::ofstream ofs(scoreFile);
	if(!ofs){
		CCLOG("open file %s failed:%s(%d)",scoreFile.c_str(),strerror(errno),errno);
		return;
	}
	std::for_each(scores.begin(),scores.end(),[&ofs](HelloResource::resource_object_item::const_reference it){
		ofs << it.first << "\t" << it.second << std::endl;
	});
 }
 class load_configure{
 public:
	 load_configure(){
		 load_items();
		 load_scroes();
	 }
 };
 }


 HelloResource::resource_object_item& HelloResource::object_items = items;
 HelloResource::resource_object_item& HelloResource::score_items = scores;




HelloResource* HelloResource::instance(){
	static HelloResource inst;
	static load_configure configure;
	return &inst;
}

void HelloResource::update(const std::string& key, const std::string& val) {
	score_items[key] = val;
	update_scores();
}

一个简单的使用


CCScene* HelloWorld::scene()
{
    CCScene *scene = CCScene::create();
    HelloWorld *layer = HelloWorld::create();
    scene->addChild(layer);
    return scene;
}

class score_context{
public:
	int counts;
	bool add;
public:
	score_context(int c,bool a):counts(c),add(a){

	}
};
void HelloWorld::spriteScoreDone(CCNode* pSender){
	 CCLabelTTF* item = ( CCLabelTTF*)pSender;
	 const std::string& curScoreString = HelloResource::instance()->cast<std::string>(senceName + ".score.cur.label");
	 std::string scoreString;
	 switch(item->getTag()){
	case emDispear: {
		score_context* sc = (score_context*) item->getUserData();
		int score = 10 * std::pow(1.1, sc->counts);
		curScore = sc->add ? curScore + score : curScore - score;
		scoreString = curScoreString + cast_to<std::string>(curScore);
		curScoreLabel->setString(scoreString.c_str());
		sc->counts--;
		item->setTag(0 == sc->counts ? emChanged : emDispear);
		item->runAction(CCSequence::create(
				CCBlink::create(0.1f,1),
				CCCallFuncN::create(this,callfuncN_selector(HelloWorld::spriteScoreDone)),
			NULL)
		);
		break;
	}
	case emChanged: {
		item->stopAllActions();
		int maxScore = HelloResource::instance()->cast<int>(senceName + ".score.max.value");
		if (curScore <= maxScore) {
			return;
		}
		maxScoreLabel->setTag(emFocus);
		maxScoreLabel->runAction(CCSequence::create(
				CCBlink::create(0.5f,1),
				CCCallFuncN::create(this,callfuncN_selector(HelloWorld::spriteScoreDone)),
			NULL)
		);
		break;
	}
	case emFocus: {
		item->stopAllActions();
		const std::string& maxScoreString = HelloResource::instance()->cast<std::string>(senceName + ".score.max.label");
		scoreString = maxScoreString + cast_to<std::string>(curScore);
		maxScoreLabel->setString(scoreString.c_str());
		HelloResource::instance()->set(senceName + ".score.max.value",	curScore);
		break;
	}
	 default:{
		 break;
	 }
	 }
}
void HelloWorld::update_score(int counts,bool add){
	const std::string& curScoreString = HelloResource::instance()->cast<std::string>(senceName + ".score.cur.label");
	std::string scoreString = curScoreString + cast_to<std::string>(curScore);
	curScoreLabel->setUserData(new score_context(counts,add));
	curScoreLabel->setTag(emDispear);
	curScoreLabel->runAction( CCSequence::create(
			CCBlink::create(0.1f,1),
			CCCallFuncN::create( this,callfuncN_selector(HelloWorld::spriteScoreDone)),
		NULL)
	);
}

void HelloWorld::spriteActionDone(CCNode* pSender){
	CCMenuItemImage* item = (CCMenuItemImage*)pSender;
	switch(item->getTag()){
	case emDispear : {
	    CCParticleExplosion* explosion = CCParticleExplosion::create();
	    explosion->setPosition(ccp(item->getContentSize().width / 2,item->getContentSize().height / 2));
	    explosion->setDuration(3.0f);
	    item->addChild(explosion,0,1000);
	    item->setTag(emChanged);
		item->runAction(CCSequence::create(
				CCFadeIn::create(0.5),
				CCCallFuncN::create( this,callfuncN_selector(HelloWorld::spriteActionDone)),
				NULL));
		break;
	}
	case emChanged:{
		item->setTag(emFocus);
		updateSpriteItem(item);
		item->runAction(CCSequence::create(
				CCLiquid::create(2.5f,CCSize(50,50),1,1),
				CCCallFuncN::create( this,callfuncN_selector(HelloWorld::spriteActionDone)),
				NULL));
		item->removeChild(item->getChildByTag(1000),true);
		break;
	}
	case emFocus:{
		CCLOG("item action done!!!");
		item->stopAllActions();
		break;
	}
	default:{
		CCLOG("Unknown action done!!!");
		break;
	}
	}
}

void HelloWorld::flush_sprite(bool suc){
	std::for_each(selectedSprites.begin(),selectedSprites.end(),[&suc,this](std::map<void*,bool>::const_reference it){
		CCMenuItemImage* item = (CCMenuItemImage*)it.first;
		item->stopAllActions();
		item->setRotation(0);
		if(!suc){
			return;
		}
		item->setTag(emDispear);
		item->runAction( CCSequence::create(
				CCFadeOut::create(0.5),
				CCCallFuncN::create( this,callfuncN_selector(HelloWorld::spriteActionDone)),
				NULL) );
	});
	update_score(selectedSprites.size(),suc);
	updateBgMusic(suc ? emSuc : emFai);
	selectedSprites.clear();
}

CCMenuItemImage* HelloWorld::updateSpriteItem(CCMenuItemImage* item ){
	int index = rand() % this->allSprites.size();
	const SpriteContex* spriteContext = &this->allSprites[index];
	if(NULL == item){
		item = CCMenuItemImage::create(
				spriteContext->normalImg.c_str(),
				spriteContext->selectImg.c_str(),
				this,
				menu_selector(HelloWorld::menuSelectedCallback));
	}else{
		item->setNormalImage(CCSprite::create(spriteContext->normalImg.c_str()));
		item->setSelectedImage(CCSprite::create(spriteContext->selectImg.c_str()));
	}
	this->sprites[item] = spriteContext;
	item->setUserData((void*)spriteContext);
	return item;
}

void HelloWorld::updateBgMusic(int val) {
    const char* szEfFile = NULL;
    CocosDenshion::SimpleAudioEngine* musicEngine = CocosDenshion::SimpleAudioEngine::sharedEngine();
    switch(val){
    case emSuc:{
    	szEfFile = this->sucMusic.c_str();
    	break;
    }
    case emFai:{
    	szEfFile = this->faiMusic.c_str();
    	break;
    }
    }
    musicEngine->stopAllEffects();
    musicEngine->playEffect(szEfFile);
}

bool HelloWorld::found_all_sprite(const SpriteContex* context,int counts)const{
	typedef std::map<void*,const SpriteContex*>::const_reference sprite_ref;
	int item_counts = std::count_if(sprites.begin(),sprites.end(),[&context](sprite_ref item){
		return (*(item.second) == *context);
	});
	CCLOG("item_counts = %d,input counts = %d",item_counts,counts);
	return item_counts == counts;
}


void HelloWorld::menuSelectedCallback(CCObject* pSender){
	CCMenuItemImage* pSprite = (CCMenuItemImage*)pSender;
	const SpriteContex* sel = (const SpriteContex*)pSprite->getUserData();
	CCLOG("%s selected",sel->name.c_str());
	typedef std::map<void*,const SpriteContex*>::const_reference sprite_ref;

	if(selectedSprites.empty()){
		std::for_each(sprites.begin(),sprites.end(),[this,&sel](sprite_ref it){
			if(*sel == *(it.second)){
				this->selectedSprites[it.first] = false;
			}
		});
	}
	if(selectedSprites.find(pSprite) == selectedSprites.end()){
		flush_sprite(false);
		return;
	}
	selectedSprites[pSprite] = true;
	CCRepeatForever* forever = CCRepeatForever::create(CCRotateBy::create(0.5f, 360));
	pSprite->runAction(forever);
	int size = std::count_if(selectedSprites.begin(),selectedSprites.end(),[](std::map<void*,bool>::const_reference it){
		return it.second;
	});
	if(size == selectedSprites.size()){
		flush_sprite(true);
		return;
	}
	CCLOG("%s selected : %d == %d", sel->name.c_str(), selectedSprites.size(), size);
}


void HelloWorld::initScoreSystem(const HelloResource& score,CCLabelTTF*& scoreLabel){
	if(!score){
		CCLOG("get score information failed");
		return;
	}
	std::string maxVal = score.cast<std::string>("label") + score.cast<std::string>("value");
    scoreLabel = CCLabelTTF::create(maxVal.c_str(), "Arial", HelloResource::instance()->cast<int>("font.size"));
    scoreLabel->setColor(ccRED);
    scoreLabel->setPosition(ccp(score.cast<int>("posion.x"),score.cast<int>("posion.y")));
    this->addChild(scoreLabel);
}

bool HelloWorld::init()
{
    //////////////////////////////
    // 1. super init first
    if ( !CCLayer::init() )
    {
        return false;
    }
    curScore = 0;
    //setTouchEnabled(true);

    std::stringstream ss;
    ss << "sence[" << HelloResource::instance()->cast<int>("cur_sence") << "]";
    senceName = ss.str();
    CCLOG("get %s information ...",senceName.c_str());
    HelloResource hr = HelloResource::instance()->cast<HelloResource>(senceName);
    if(!hr){
		CCLOG("get %s information failed",senceName.c_str());
		return false;
    }
    hr.for_each("sprite",[this](const HelloResource& sprite){
    	if(!sprite){
    		CCLOG("get sprite information failed");
    		return;
    	}
    	SpriteContex context = {
    			sprite.cast<unsigned int>("property"),
    			this->senceName,
    			sprite.cast<std::string>("normal"),
    			sprite.cast<std::string>("selected")
    	};
    	this->allSprites.push_back(context);
    }).on<HelloResource>("back_ground",[this](const HelloResource& bg){
    	if(!bg){
    		CCLOG("get back ground information failed");
    		return;
    	}		
    	HelloWorld* that = this;
    	bg.on<std::string>("music",[](const std::string& music){
    		if(music.empty()){
        		CCLOG("get back ground music failed");
        		return;
    		}
            CocosDenshion::SimpleAudioEngine* musicEngine = CocosDenshion::SimpleAudioEngine::sharedEngine();
            musicEngine->stopBackgroundMusic(true);
            musicEngine->playBackgroundMusic(music.c_str(),true);
    	}).on<std::string>("img",[&that](const std::string& img){
    		if(img.empty()){
        		CCLOG("get back ground img failed");
        		return;
    		}
            CCSprite* bg = CCSprite::create(img.c_str());
            CCSize visibleSize = CCDirector::sharedDirector()->getVisibleSize();
    		bg->setPosition(ccp(visibleSize.width/2, visibleSize.height / 2));
            that->addChild(bg,-10);
    	});
    }).on<HelloResource>("score",[this](const HelloResource& score){
    	if(!score){
    		CCLOG("get score information failed");
    		return;
    	}
		auto that = this;
    	score.on<HelloResource>("max",[&that](const HelloResource& max){
    		that->initScoreSystem(max,that->maxScoreLabel);
    	}).on<HelloResource>("cur",[&that](const HelloResource& cur){
    		that->initScoreSystem(cur,that->curScoreLabel);
    	});
    }).on<HelloResource>("head",[this](const HelloResource& head){
        if(!head){
    		CCLOG("get head information failed");
    		return;
        }
        CCSprite* pSprite = CCSprite::create(head.cast<std::string>("img").c_str());
        pSprite->setPosition(ccp(head.cast<int>("posion.x"),head.cast<int>("posion.y")));
        this->addChild(pSprite, 0);
    }).on<std::string>("title",[this](const std::string& title){
		if(title.empty()){
    		CCLOG("get title information failed");
    		return;
        }
        CCLabelTTF* pLabel = CCLabelTTF::create(title.c_str(), "Arial", HelloResource::instance()->cast<int>("font.size"));
        CCSize visibleSize = CCDirector::sharedDirector()->getVisibleSize();
        CCPoint origin = CCDirector::sharedDirector()->getVisibleOrigin();
        pLabel->setPosition(ccp(origin.x + visibleSize.width/2,
                                origin.y + visibleSize.height - pLabel->getContentSize().height));
        this->addChild(pLabel, 1);
	}).on<HelloResource>("menu.return",[this](const HelloResource& rt) {
		if(!rt) {
			CCLOG("get return  menu information failed");
			return;
		}
		CCMenuItemImage *pReturnItem = CCMenuItemImage::create(
			rt.cast<std::string>("img.normal").c_str(),
			rt.cast<std::string>("img.select").c_str(),
			this,
			menu_selector(HelloWorld::menuCloseCallback));
        CCSize visibleSize = CCDirector::sharedDirector()->getVisibleSize();
        CCPoint origin = CCDirector::sharedDirector()->getVisibleOrigin();
        pReturnItem->setPosition(ccp(origin.x + visibleSize.width - pReturnItem->getContentSize().width/2 ,
								origin.y + pReturnItem->getContentSize().height/2));
		CCMenu* pMenu = CCMenu::create(pReturnItem, NULL);
		pMenu->setPosition(ccp(rt.cast<int>("x"),rt.cast<int>("y")));
		this->addChild(pMenu, 1);
	}).on<HelloResource>("grid",[this,&hr](const HelloResource& grid){
		if(!grid) {
			CCLOG("get grid information failed");
			return;
		}
    	const int colCount = grid.cast<int>("col");
    	const int rowCount = grid.cast<int>("raw");
    	const int imgWidth = grid.cast<int>("size");
    	const int maxItem = colCount * rowCount;
    	CCArray* items = CCArray::createWithCapacity(maxItem);
    	for(int i = 1,x = 1,y = 1; i <= maxItem; ++i){
    		CCMenuItemImage* pSprite = this->updateSpriteItem(NULL);
    		pSprite->setPosition(ccp(x*imgWidth,y*imgWidth));
    		items->addObject(pSprite);
    		(i % colCount == 0)? (x = 1,++y) : (++x);
    	}
        CCMenu* pMenu = CCMenu::createWithArray(items);
        pMenu->setPosition(ccp(grid.cast<int>("x"),grid.cast<int>("y")));
        this->addChild(pMenu, 1);
        items->release();
    }).on<HelloResource>("state",[this](const HelloResource& state){
		if(!state) {
			CCLOG("get state information failed");
			return;
		}
		this->sucMusic = state.cast<std::string>("succ.music");
		this->faiMusic = state.cast<std::string>("fail.music");
    });
    return true;
}


void HelloWorld::menuCloseCallback(CCObject* pSender)
{
	this->allSprites.clear();
	CocosDenshion::SimpleAudioEngine::sharedEngine()->stopBackgroundMusic(true);
	CCDirector::sharedDirector()->replaceScene(WellCome::scene());
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值