cocos2d-x实现游戏剧情对话打字效果
目录
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;
}
附上效果图两张
初次写博文,有什么不对的地方请指正,谢谢!