cocos2d-x之CCGUI设计与实现(2)RichTextBox的实现(支持多颜色、表情、超链接)

26 篇文章 0 订阅
10 篇文章 0 订阅

Cocos2d-x提供了基本CCLabelTTF用于文本的绘制,文本底层的实现流程是这样的,字符串string先用本地API转化成CCImage,这一步依赖平台接口,然后再由CCImage转化成CCTexture2D纹理,进而用于文本的渲染。

         那么如何通过CCLabelTTF等字体类实现一个RichTextBox,支持多颜色、换行、表情(图片)、超链接呢?

         我们不打算从OpenGL底层来做这个工作,因为那样工作量非常大,而是在已有的cocos2d-x接口上进行组合。

         由于3年前用过windowsGDI底层接口做过一个彩色文本编辑器,对于拼接问题也是手到擒来,甚至感觉这个相对还要简单很多。

         先分解工作及流程:

(1)      多颜色:多个不同颜色的CCLabelTTF拼在一起就是一个多颜色文本了。

(2)      换行:这个相对棘手,换行需要考虑当前RichTextBox的高度和宽度,如果当前行的字符数已满,需要被动换行,另外如果有\n换行符,需要主动换行。

(3)      表情:表情即图片,实现起来比文字要简单。

(4)      超链接:由于采用CCGUI系统里面的TextBox作为基本拼接元,本身就具有接受点击的潜质,只需要设置是否可触摸即可。

(5)      文本里面每个字符的宽度都需要精确计算,而计算的代价比较大(PC上一个字符计算的时间代价大概为1ms),但由于字符数一定,常用中英文字符也就几千个而已,因此可以在游戏运行时做缓存,这样能够极大提高效率。缓存算法不是一次性计算所有字符,而是每帧计算若干个字符,这样能够保证游戏的流畅性,加载可以放在游戏运行时进行。

 

这里详细说明一下换行的实现思路,因为这是这个控件的比较麻烦的地方,弄清楚后其他的都好说。

对于新加(append)进RichTextBox的文本,首先计算该文本的像素宽度(width),宽度计算出来之后,逻辑伪代码如下:

If 插入行剩余宽度 >= width then

         直接插入文本

更新插入位置(x,y)

Else

         计算插入行能插入多少字符

         填满插入行

         计算剩余宽度

         While(有剩余)

                  If 剩余宽度 > RichTextBox.widththen

                            填满本行

                            计算剩余宽度

                   Else

                            直接插入文本

                            更新插入位置

                   End

End

End

 

看起来不是很复杂,但是注意的细节还是比较多的,首先是文本必须是utf8格式,windows默认是gbk,需要转换(采用cocos2d-x的附带的第三方iconv库),转换之后需要计算该文本里面一个utf8字符占了多少char字符,通常一个utf8格式的汉字占用3个char字符;另外一个是计算每个utf8字符的像素宽度,这个我是直接用CCLabelTTF来计算,如果自己写计算宽度的API,也是需要依赖平台的,如windows平台可能要用到GetCharWidth32等     API,再换到IOS,又是另外的计算方法,这个工作量也比较大,希望后面能有人整理出来,不过现在我们就偷偷懒,而且基于上面第(5)点所说的优化方案,其实没有可担忧的。

 

 来新公司后,用了这套GUI设计方案,由于不再属于个人作品,而是严肃的商业代码,希望后面能够开源。

目前模仿CEGUI写完了所有的基本控件(一个星期时间),在实现上也参考了很多CEGUI的代码,这样能够在很大程度上与方家的API保持一致。

博客里面会大致讲解比较麻烦的控件实现方式,如模仿IOS系统GUI的NumberPicker,以及有翻页功能的ScrollView,各位看官,博客比代码慢很多,还请见谅。


  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 6
    评论
评论 6
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值