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

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

先看一下xml文件

[html]  view plain copy
  1. <?xml version="1.0" encoding="UTF-8"?>  
  2.   
  3. <plist version="1.0">  
  4.   <talk anchor="0" icon="talk/icon.png" name="路人甲:" content="  听说他已经30了。"/>  
  5.   <talk anchor="1" icon="talk/icon.png" name="路人乙:" content="  是啊!都30了还叫to3(奔三),装嫩呢!"/>  
  6.   <talk anchor="0" icon="talk/icon.png" name="路人甲:" content="  哈哈哈……"/>  
  7. </plist>  

anchor:对齐方式 0左 1右



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

[cpp]  view plain copy
  1. class TalkNode  
  2. {  
  3. public:  
  4.         bool anchor;  
  5.         std::string icon;  
  6.         std::string name;  
  7.         std::string content;  
  8.         void init(TiXmlNode *node);  
  9.         bool getAnchor(){return anchor;};  
  10.         const char* getIcon(){returnicon.c_str();};  
  11.         const char* getName(){returnname.c_str();};  
  12.         const char* getContent(){returncontent.c_str();};  
  13.         std::string getContentByLength(intlength);  
  14.         int contentLeght;  
  15.         int getContentLength();  
  16. };  


再看TalkNode的实现

[cpp]  view plain copy
  1. voidTalkNode::init(TiXmlNode *node)  
  2. {  
  3.         TiXmlElement *element =node->ToElement();  
  4.    
  5.         int intValue;  
  6.         if(element->QueryIntAttribute("anchor", &intValue) ==TIXML_SUCCESS)  
  7.         {  
  8.                anchor = intValue;  
  9.         }  
  10.         else  
  11.         {  
  12.                anchor = false;  
  13.         }  
  14.          
  15.         name =element->Attribute("name");  
  16.         icon =element->Attribute("icon");  
  17.         content =element->Attribute("content");  
  18.         contentLeght = 0;  
  19.    
  20.         int length = content.length();  
  21.         int i = 0;  
  22.         while(i < length)  
  23.         {  
  24.                char ch = getContent()[i];  
  25.                //重点在这里  
  26.                //中文在ASCII码中是-127~0  
  27.                if (ch > -127 && ch< 0)  
  28.                {  
  29.                        //这里为什么+=3呢  
  30.                        //因为一个中文占3个字节  
  31.                        i+=3;  
  32.                }  
  33.                else  
  34.                {  
  35.                        i++;  
  36.                }  
  37.                contentLeght++;  
  38.         }  
  39. }  
  40. //获取内容的总长度  
  41. int TalkNode::getContentLength()  
  42. {  
  43.     return contentLeght;  
  44. }  
  45.   
  46. //返回所需长度的字符串  
  47. std::string TalkNode::getContentByLength(int length)  
  48. {  
  49.     if (length >= contentLeght)  
  50.     {  
  51.         return getContent();  
  52.     }  
  53.     int i = 0;  
  54.     int index = 0;  
  55.     while(index < length)  
  56.     {  
  57.         char ch = getContent()[i];  
  58.         //这里上面说过了  
  59.         if (ch > -127 && ch < 0)  
  60.         {  
  61.             i+=3;  
  62.         }  
  63.         else  
  64.         {  
  65.             i++;  
  66.         }  
  67.         index++;  
  68.     }  
  69.   
  70.     //截取strng  
  71.     std::string str = content.substr(0, i);  
  72.     return str;  
  73. }  

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

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

[cpp]  view plain copy
  1. std::vector <TalkNode*> talkList;  
  2. void Talking::readXml(const char *filename)  
  3. {  
  4.     unsigned long filesize;  
  5.     const char *path = CCFileUtils::sharedFileUtils()->fullPathFromRelativePath(filename);  
  6.     char *buffer = (char *)CCFileUtils::sharedFileUtils()->getFileData(path, "rb", &filesize);  
  7.   
  8.   
  9.     if (buffer == NULL)  
  10.     {  
  11.         return;  
  12.     }  
  13.   
  14.     TiXmlDocument doc;  
  15.     doc.Parse(buffer);  
  16.     TiXmlNode *root = doc.FirstChild("plist");   
  17.   
  18.     if (root)  
  19.     {  
  20.         TiXmlElement *element = root->ToElement();  
  21.         for (TiXmlNode* entityNode = root->FirstChild(); entityNode; entityNode = entityNode->NextSibling())  
  22.         {  
  23.             TalkNode *node= new TalkNode();  
  24.             node->init(entityNode);  
  25.             talkList.push_back(node);  
  26.         }  
  27.         talkCount = talkList.size();  
  28.     }  
  29. }  



到这里就可以实现打字效果了,但我们还得自动换行,这个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字符串就可以了

[cpp]  view plain copy
  1. void Talking::logic(float cTime)  
  2. {  
  3.     TalkNode* node = (TalkNode*)talkList[talkIndex];  
  4.     if (wordCount > node->getContentLength())  
  5.     {  
  6.         return;  
  7.     }  
  8.   
  9.   
  10.     wordCount++;  
  11.     CCLabelTTF* label = (CCLabelTTF*)this->getChildByTag(kTalkingLabelTag);  
  12.     label->setString(node->getContentByLength(wordCount).c_str());  
  13. }  

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

[cpp]  view plain copy
  1. bool Talking::ccTouchBegan(CCTouch *pTouch, CCEvent *pEvent)  
  2. {  
  3.     TalkNode* node = (TalkNode*)talkList[talkIndex];  
  4.     if (wordCount < node->getContentLength())  
  5.     {  
  6.         wordCount = node->getContentLength();  
  7.     }  
  8.       
  9.     return true;  
  10. }  



附上效果图两张



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值