cocos2d读取xml文件

时间:2022-04-27 10:05:35

1.代码

//HXmlParse.h

#pragma once
#include "cocos2d.h"
#include "CCSAXParser.h"
#include "CCObject.h"
#include "CCDictionary.h"
using namespace cocos2d;
class HXmlParse : public CCObject,public CCSAXDelegator
{
public:
static HXmlParse* parserWithFile(const char* tmxFile,bool isJumpHead=false);
bool initXmlParse(const char* xmlName);

void startElement(void *ctx,const char* name,const char** atts);
void endElement(void *ctx,const char* name);
void textHandler(void *ctx, const char *s, int len);

std::string root_name;
bool isJumpHeadData;
CCDictionary *mDic;
HXmlParse(void);
~HXmlParse(void);
private:
std::string startXmlElement;
std::string endXmlElement;
std::string currString;
};

//HXmlParse.cpp

#include "HXmlParse.h"
#include "CCSAXParser.h"

HXmlParse::HXmlParse(void)
{
}


HXmlParse::~HXmlParse(void)
{
}

HXmlParse* HXmlParse::parserWithFile(const char* tmxFile,bool isJumpHead)
{
HXmlParse *pRet=new HXmlParse();
pRet->isJumpHeadData=isJumpHead;
if(pRet->initXmlParse(tmxFile)){
pRet->autorelease();
return pRet;
}
CC_SAFE_DELETE(pRet);
return NULL;
}

bool HXmlParse::initXmlParse(const char* xmlName)
{
mDic=new CCDictionary();
CCSAXParser _pair;
if(false==_pair.init("UTF-8"))
{
CCLOG("---please use utf-8");
return false;
}
_pair.setDelegator(this);
const char* _path=CCFileUtils::sharedFileUtils()->fullPathFromRelativePath(xmlName);
return _pair.parse(_path);
}

void HXmlParse::startElement(void *ctx,const char* name,const char** atts)
{
CC_UNUSED_PARAM(ctx);
startXmlElement=(char*)name;
if(!isJumpHeadData){	//跳过数据头(false)
isJumpHeadData=true;
root_name=startXmlElement;
return;
}
else{

}
if(atts){	 //有属性值
int i=0;
CCString *datastr;
while(atts[i])			//atts存有name的属性(单数是属性名,双数是数值)
{	
datastr=new CCString();
//	 CCString datastr;
std::string keystr(atts[i]);		//属性名
datastr->m_sString=atts[i+1];		//数值
CCLOG("atts[%d]=%s keystr=%s",i,atts[i],keystr.c_str());
CCLOG("atts[%d]=%s data=%s",i+1,atts[i+1],datastr->m_sString.c_str());
mDic->setObject(datastr,keystr);	 //setobject()传进去Object是传引用,所以每次调用都要不同的对象。(要不然会覆盖)
//	 if(mDic->valueForKey())
//	 CCLOG("count=%d",mDic->count());
std::string teststr("name");
CCLog("-----key:%s, value:%s",teststr.c_str(),mDic->valueForKey(teststr)->m_sString.c_str());
i=i+2;
}
}
CCLOG(startXmlElement.c_str());
}

void HXmlParse::endElement(void *ctx,const char* name)
{
CC_UNUSED_PARAM(ctx);
endXmlElement=(char*)name;
if(endXmlElement==root_name){
CCLOG("close xml read!");
isJumpHeadData=false;
root_name="";
return;
}

}

void HXmlParse::textHandler(void *ctx, const char *s, int len)
{
CC_UNUSED_PARAM(ctx);
currString=std::string((char*)s,0,len);
CCLOG("s_len=%d",strlen(s));
CCString *ccstr=new CCString();
ccstr->m_sString=currString;
if(root_name!=""){
mDic->setObject(ccstr,startXmlElement);
//	 CCLOG("count=%d",mDic->count());
}
}

2.解释

CCSAXParser类可以解析xml文件,但是需要指定CCSAXDelegator。由于CCSAXDelegator中有 3个纯虚函数startElement,textHandler和endElement,所以HXmlParse实现这3个函数。

3.进制转换

CCString::intValue() ,CCString::boolValue(), CCString::m_sString.c_str() 等可以将CCString对象转成所需的类型。

4.动画的回调

void HelloWorld::menuLeftCallback(CCObject* pSender)
{
sprite->stopAllActions();
CCAnimation *animation=GetAnimate("walk_l_000",6,0.2f);

CCRepeat *repeat=CCRepeat::actionWithAction(CCAnimate::actionWithAnimation(animation),1);

CCPoint pos=sprite->getPosition();
CCActionInterval *moveto=CCMoveTo::actionWithDuration(1,ccp(pos.x-100,pos.y));
CCActionInstant *pflipX=CCFlipX::actionWithFlipX(false);
CCArray *a=CCArray::array();
a->addObject(repeat);
a->addObject(moveto);

CCFiniteTimeAction *run_action=CCSpawn::actionWithArray(a);

CCFiniteTimeAction *actionMoveDone=CCCallFuncN::actionWithTarget(this,callfuncN_selector(HelloWorld::LeftIdleCallBack));//动作回调函数
sprite->runAction(pflipX);		//取消X翻转
sprite->runAction(CCSequence::actions(run_action,actionMoveDone,NULL));	//“移动动画”和“回调动作”形成序列
}

void HelloWorld::LeftIdleCallBack(CCNode* sender)
{
CCAnimation *idle_anim=GetAnimate("stand_l_000",4,0.2f);
CCRepeatForever *forever_Idle_anim=CCRepeatForever::actionWithAction(CCAnimate::actionWithAnimation(idle_anim));
sprite->stopAllActions();

sprite->runAction(CCSpawn::actions(forever_Idle_anim,NULL));//静止时动画
}