博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
cocos2dx 富文本框,支持换行,支持神情(支持汉字截断无乱码)
阅读量:4553 次
发布时间:2019-06-08

本文共 5950 字,大约阅读时间需要 19 分钟。

cocos2dx 富文本框,支持换行,支持表情(支持汉字截断无乱码)

小工在做了一个游戏聊天功能,里面用到插入表情的富文本和换行的问题;

先看效果,不是你要的效果,可return;(截图由于:输入的问题,未能输入汉字)

 

 

实现方式;

定义一个layer,在layer上摆放文本,表情,按钮,等控件,由此来形成一个多控件组成的一个富文本;

表情:仿照QQ,用的是【xy】这种方式来表示,如【00】,对应资源就是00.png

换行:就是是把超出指定宽度的内容回车,实现换行(主要是坐标x=起始位置)当然涉及到表情等,容易出问题;

例子

string m_sString = “待到山花烂漫时,他在花丛中笑【12】丛中笑【12】丛中笑【12】丛中笑【12】”;

 

下面伪代码实现

处理string 得到string的真实个数长度,一个汉字,一个字母代表一个长度;

创建循环体,分别来遍历没一个汉字或者是字母+特殊字符等,遇到【就判断是否是表情,如果是表情就添加表情,表情添加之前需要将表情之前的汉字等先排列上,表情排列后继续,进行遍历;

如果发现当前遍历的内容所占的屏幕长度就进行换行。表情的长度=getContextSize().width 来获取;

 

 

 

具体实现如代码

 

void MessageItem::changeLine(){      CCArray *array = getChildren();    for (int i=0; i
count(); i++) { CCNode* node =(CCNode*) array->objectAtIndex(i); node->setPositionY(m_iDefaultSize); }}void MessageItem::showText(const ccColor3B cColor3B ){ bool bDoubleLine=false; int posX= 0;//读取内容的长度小标 int iMsgEnd = 1; int iMsgStart =1; int width = m_iPannelWidth ;//显示面板的宽度 std::string r=""; //按照一个汉字一个长度,一个字母或者是特殊符号一个长度,得到的长度;(这样避免换行的时候汉字被分开,出现乱码现象) int iRealLength = Tools::getRealStringLength(m_TotalMsg); CCLabelTTF* tempTextView = CCLabelTTF::create(); tempTextView->setFontName("Arial-BoldMT"); tempTextView->setFontSize(24); while( (r= Tools::subString(m_TotalMsg,iMsgStart,iMsgEnd))!= "") { //先判断当前读取的字符内容是否是表情 if(r[r.length()-1]=='[') { std::string tmp = Tools::subString(m_TotalMsg,iMsgEnd,iMsgEnd+3); if(tmp[3]==']'&&isNumber(tmp[1])&&isNumber(tmp[2]))//face { //表情前面若有内容的处理 if(iMsgEnd-iMsgStart>0) { CCLabelTTF* textView = CCLabelTTF::create(); textView->setFontName("Arial-BoldMT"); textView->setFontSize(24); textView->setColor(cColor3B); textView->setString(r.substr(0,r.length()-1).c_str()); textView->setPosition(ccp(m_LeftMsg_x+posX, 0)); textView->setAnchorPoint(ccp(0, 0)); posX+=textView->getContentSize().width; this->addChild(textView); } //如果有表情的处理 char temp[10] = {0}; if(tmp[1]-'0' == 0) { sprintf(temp, "%d.png",tmp[2]-'0'); } else { sprintf(temp, "%d%d.png",tmp[1]-'0',tmp[2]-'0'); } bLineHaveFace = true; CCSprite *sp = CCSprite::create(temp); sp->setScaleX(0.6); sp->setScaleY(0.6); sp->setAnchorPoint(ccp(0, 0)); //如果最后表情在一行的最后的换行处理 if(sp->getContentSize().width+posX>width) { posX=0; if (m_bLimitOneLine == true) { break; } changeLine(); bDoubleLine=true; } iMsgEnd+=4; iMsgStart=iMsgEnd; sp->setPosition(ccp(m_LeftMsg_x+posX, 0)); posX+=sp->getContentSize().width*0.6; this->addChild(sp); if(iMsgEnd>iRealLength) { break; } continue; } } tempTextView->setString(r.c_str()); //如果读取到都是无表情的内容,如下进行换行; if(tempTextView->getContentSize().width+posX+24 >= width) { CCLabelTTF* textView = CCLabelTTF::create(); textView->setFontName("Arial-BoldMT"); textView->setFontSize(24); textView->setColor(cColor3B); textView->setString(r.c_str()); textView->setPosition(ccp(m_LeftMsg_x+posX, 0)); textView->setAnchorPoint(ccp(0, 0)); this->addChild(textView); iMsgEnd++; iMsgStart=iMsgEnd; posX=0; if(iMsgEnd>iRealLength) { break; } if (m_bLimitOneLine) { break; } changeLine(); bDoubleLine=true; } else { iMsgEnd++; if(iMsgEnd>iRealLength) { CCLabelTTF* textView = CCLabelTTF::create(); textView->setFontName("Arial-BoldMT"); textView->setColor(cColor3B); textView->setFontSize(24); textView->setString(r.c_str()); textView->setPosition(ccp(m_LeftMsg_x+posX, 0)); textView->setAnchorPoint(ccp(0, 0)); this->addChild(textView); break; } } } if(bDoubleLine) { setContentSize(CCSizeMake(width, m_iDefaultSize*2)); m_pTypeName->setPositionY(m_iDefaultSize); m_pUserName->setPositionY(m_iDefaultSize); } else { setContentSize(CCSizeMake(width, m_iDefaultSize)); m_pTypeName->setPositionY(0); m_pUserName->setPositionY(0); }}// 截取字符,必满乱码的处理;std::string Tools::subString(std::string str ,int start ,int end){ if(typeid(str)==typeid(string) && str.length()>0) { int len=str.length(); string tmp=""; //先把str里的汉字和英文分开 vector
dump; int i=0; while(i
0?end:iDumpSize; if(start<0||start>end) return ""; for(i=start; i<=end; i++) { tmp+=dump[i-1]; } return tmp; } else { printf("str is not string\n"); return ""; }}//获取字符串的真实长度处理int Tools::getRealStringLength(std::string str){ int i=0; int len=str.length(); int r=0; while(i

 

如上基本上处理了一个富文本的基本操作,功能比较简单,但是做起来比较容易出问题,像换行,插入表情,截取汉字这个三个问题

转载于:https://www.cnblogs.com/xiaoleiel/p/8301150.html

你可能感兴趣的文章
Jq 遍历each()方法
查看>>
Android源码分析:Telephony部分–phone进程
查看>>
关于 redis.properties配置文件及rule
查看>>
WebService
查看>>
关于Java中重载的若干问题
查看>>
Java中start和run方法的区别
查看>>
23种设计模式中的命令模式
查看>>
[转载]年薪10w和年薪100w的人,差在哪里?
查看>>
shell 日期参数
查看>>
package的使用
查看>>
括号生成
查看>>
优秀的前端需要做到什么?
查看>>
aws cli command line interface的安装与使用
查看>>
10)将地址换成常量
查看>>
cocos2d-x3.0 解释具体的新的物理引擎setCategoryBitmask()、setContactTestBitmask()、setCollisionBitmask()...
查看>>
Cocos2d-x
查看>>
FIR滤波器设计
查看>>
1005 继续(3n+1)猜想 (25 分)
查看>>
【Uva 1252】Twenty Questions
查看>>
1_访问命令行
查看>>