Label可以通过getLetter(i)获取位于字符串i位置的字符(不支持system类型创建的label,我这边是用TTF),然后通过setColor设置字符的颜色。但是有时候i不确定,所以我在这边自己做了一些处理。比如“获得了紫色品质的装备”,想让“紫色品质”四个字变成紫色,可以这样做:“获得了#2C%s#2C的装备。然后再用String::createWithFormat()一下,就得到字符串——“获得了#2C紫色品质#2C的装备”,这里#2C代表紫色。这个可以自己设定。然后在对字符串进行处理。主要是找出并保存#2C的位置,并删除#2C。然后根据找出来的#2C的位置,进行getLetter(i),再setColor()。部分代码如下:
vector<int> posVec; vector<int> colorVec; posVec.clear(); int position=0; int lastPos = 0; int lastTraversalPos = 0; while((position = strContent.find("#",position))!=string::npos) { int cPosition = strContent.find("C",position); if (cPosition != string::npos && (cPosition - position) > 1 && strContent[cPosition] == 'C') {// 如果%后面找不到C或者%C中间没有数字则不进来 int color = 0; for (int m = 1; m < (cPosition - position); m ++) { auto charColor = strContent.substr(position + m,1); color += atoi(charColor.c_str()) + (cPosition - position - m - 1) * 10; } if (position != lastPos) { int strNum = 0; int m = lastTraversalPos; for (; m < position; ) { char c = strContent[m]; if (c >= 0 && c <= 127) { strNum ++; m += 1; } else if (c >= 192 && c <= 223) { strNum ++; m += 2; } else if (c >= 224 && c <= 239) { strNum ++; m += 3; } else if (c >= 240 && c <= 247) { strNum ++; m += 4; } else { strNum ++; m += 3; } } position = strNum + lastPos; lastPos = position; lastTraversalPos = m; } posVec.push_back(position); colorVec.push_back(color); //position=s.find_first_of(flag,position); strContent.erase(lastTraversalPos,3); } else { position ++; } }
这里会有一个问题,就是如果你设置了文本的宽度,即setDimensions(),并且字符串的长度超过宽度的时候,会自动换行,那么Label原来的字符串就会被插入相对应个数的’n',这样你在getLetter的时候有可能获取到的不是你想要的字符。这时候就要跟到引擎代码里面去看。发现在getLetter的时候会内部会调用Label::updateContent()函数。这个函数里面会调用alignText(),这将会对字符串进行重新排版,有需要换行的话,会自动在相应位置插入'n'。所以我们可以记录下插入'n'的位置。跟着源代码进去发现在CCLabelTextFormatter.cpp里面的multilineText()函数进行插入'n'处理的。所以可以在这里面添加一个函数,获取记录下的位置。然后对我们之前保存的#2C的位置进行调整。插入的位置如果小于#2C的位置,那么#2C就要+1了。部分代码如下:
m_pLabel->setString(strContent.c_str()); m_pLabel->updateContent(); vector<int> insertCharacterPosVec = m_pLabel->getInsertCharacterPos(); for (int originalItr = 0; originalItr < posVec.size(); originalItr ++) {// 如果字符串的长度超过了文本框的宽度,会自动换行,这时候会在原来的string上插入'n',整个string长度发生改变。导致接下来的getLetter找不到想要的。所以在这里做处理。 for (int vecItr = 0; vecItr < insertCharacterPosVec.size(); vecItr ++) { if (posVec[originalItr] > insertCharacterPosVec[vecItr]) { posVec[originalItr] ++; } } }
还会有一个问题就是如果同一个Label进行多次的setString的时候可能会出现”Assertion failed: (index>=0 && index<_totalQuads),function removeQuadAtIndex”这个错误。我在setString之前调用一下label->removeAllChildrenWithCleanup(true)就好了。
写得比较乱,主要说明一下大概思路,也算是笔记吧~~ (编辑:李大同)
【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!
|