cocos2d-x实现游戏剧情对话——打字效果


cocos2d-x版本 2.0.4

做RPG游戏的时候会有剧情对,中英文混搭,要求打字效果,一个字一个字的往出蹦。

先看一下xml文件

<?xml version="1.0" encoding="UTF-8"?>

<plist version="1.0">
  <talk anchor="0" icon="talk/icon.png" name="路人甲:" content="  听说他已经30了。"/>
  <talk anchor="1" icon="talk/icon.png" name="路人乙:" content="  是啊!都30了还叫to3(奔三),装嫩呢!"/>
  <talk anchor="0" icon="talk/icon.png" name="路人甲:" content="  哈哈哈……"/>
</plist>

anchor:对齐方式 0左 1右



创建一个对话映射的节点TalkNode

class TalkNode
{
public:
        bool anchor;
        std::string icon;
        std::string name;
        std::string content;
        void init(TiXmlNode *node);
        bool getAnchor(){return anchor;};
        const char* getIcon(){returnicon.c_str();};
        const char* getName(){returnname.c_str();};
        const char* getContent(){returncontent.c_str();};
        std::string getContentByLength(intlength);
        int contentLeght;
        int getContentLength();
};


再看TalkNode的实现

voidTalkNode::init(TiXmlNode *node)
{
        TiXmlElement *element =node->ToElement();
 
        int intValue;
        if(element->QueryIntAttribute("anchor", &intValue) ==TIXML_SUCCESS)
        {
               anchor = intValue;
        }
        else
        {
               anchor = false;
        }
       
        name =element->Attribute("name");
        icon =element->Attribute("icon");
        content =element->Attribute("content");
        contentLeght = 0;
 
        int length = content.length();
        int i = 0;
        while(i < length)
        {
               char ch = getContent()[i];
               //重点在这里
               //中文在ASCII码中是-127~0
               if (ch > -127 && ch< 0)
               {
                       //这里为什么+=3呢
                       //因为一个中文占3个字节
                       i+=3;
               }
               else
               {
                       i++;
               }
               contentLeght++;
        }
}
//获取内容的总长度
int TalkNode::getContentLength()
{
	return contentLeght;
}

//返回所需长度的字符串
std::string TalkNode::getContentByLength(int length)
{
	if (length >= contentLeght)
	{
		return getContent();
	}
	int i = 0;
	int index = 0;
	while(index < length)
	{
		char ch = getContent()[i];
		//这里上面说过了
		if (ch > -127 && ch < 0)
		{
			i+=3;
		}
		else
		{
			i++;
		}
		index++;
	}

	//截取strng
	std::string str = content.substr(0, i);
	return str;
}

有同学会问TiXmlElement是哪来的? to3是用的tinyxml解析xml,度娘可以找的到。

下面看一下to3的读取xml的函数

std::vector <TalkNode*> talkList;
void Talking::readXml(const char *filename)
{
	unsigned long filesize;
	const char *path = CCFileUtils::sharedFileUtils()->fullPathFromRelativePath(filename);
	char *buffer = (char *)CCFileUtils::sharedFileUtils()->getFileData(path, "rb", &filesize);


	if (buffer == NULL)
	{
		return;
	}

	TiXmlDocument doc;
	doc.Parse(buffer);
	TiXmlNode *root = doc.FirstChild("plist"); 

	if (root)
	{
		TiXmlElement *element = root->ToElement();
		for (TiXmlNode* entityNode = root->FirstChild(); entityNode; entityNode = entityNode->NextSibling())
		{
			TalkNode *node= new TalkNode();
			node->init(entityNode);
			talkList.push_back(node);
		}
		talkCount = talkList.size();
	}
}



到这里就可以实现打字效果了,但我们还得自动换行,这个cocos2d-x的CCLabelTTF有提供这个API

CCLabelTTF * CCLabelTTF::create(const char *string, const char *fontName, float fontSize,  const CCSize& dimensions, CCTextAlignment hAlignment);

string:内容

fontName:字体

fontSize:字号

dimensions:显示框

hAlignment:对齐方式


最后在逻辑循环里更新你的CCLabelTTF字符串就可以了

void Talking::logic(float cTime)
{
	TalkNode* node = (TalkNode*)talkList[talkIndex];
	if (wordCount > node->getContentLength())
	{
		return;
	}


	wordCount++;
	CCLabelTTF* label = (CCLabelTTF*)this->getChildByTag(kTalkingLabelTag);
	label->setString(node->getContentByLength(wordCount).c_str());
}

再加上点击屏幕显示全部内容

bool Talking::ccTouchBegan(CCTouch *pTouch, CCEvent *pEvent)
{
	TalkNode* node = (TalkNode*)talkList[talkIndex];
	if (wordCount < node->getContentLength())
	{
		wordCount = node->getContentLength();
	}
	
	return true;
}



附上效果图两张





初次写博文,有什么不对的地方请指正,谢谢!



  • 0
    点赞
  • 11
    收藏
    觉得还不错? 一键收藏
  • 10
    评论
评论 10
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值