cocos2dx 3.3 Label对指定字符设置颜色

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)就好了。

写得比较乱,主要说明一下大概思路,也算是笔记吧~~

  • 3
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Box2D和Cocos2D是两个游戏开发框架。Box2D是一个用于物理模拟的开源库,可以模拟刚体的运动和碰撞等物理效果。Cocos2D是一个用于2D游戏开发的跨平台框架,提供了丰富的图形渲染和用户交互功能。\[1\] 在使用Cocos2D和Box2D进行游戏开发时,你可以利用Box2D来处理游戏中的物理效果,比如重力、碰撞和刚体运动等。Cocos2D提供了与Box2D的集成,使得开发者可以方便地在Cocos2D中使用Box2D的功能。你可以通过创建物理世界、添加刚体和设置碰撞检测等来实现游戏中的物理效果。\[2\] 如果你刚刚接触Cocos2D和Box2D,建议你先学习Cocos2D和Box2D的基础知识,然后再深入学习如何在Cocos2D中使用Box2D。你可以参考一些入门教程,比如《Cocos2D入门》和《Box2D入门》。如果你对OpenGL ES 2.0和自定义Cocos2D 2.X着色器等背景知识感到困惑,你可以查阅相关教程来获取更多的帮助。\[3\] #### 引用[.reference_title] - *1* *3* [如何使用Box2D和Cocos2D制作一款像Fruit Ninja一样的游戏-第1部分](https://blog.csdn.net/kaka626/article/details/9397825)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^insert_down1,239^v3^insert_chatgpt"}} ] [.reference_item] - *2* [用Box2D和cocos2d-x制作弹弓类游戏](https://blog.csdn.net/qq55008307/article/details/8090839)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^insert_down1,239^v3^insert_chatgpt"}} ] [.reference_item] [ .reference_list ]

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值