Cocos2d-x 更改文字换行风格 ( cocos2dx change line )

前端之家收集整理的这篇文章主要介绍了Cocos2d-x 更改文字换行风格 ( cocos2dx change line )前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。

Cocos2dx change line

在 cocos2dx change line 的实现中,我们可以简单的使用dimensions属性控制换行。使用它只需将对应的参数值传入构造函数,或者调用 setDimensions 函数即可。

它的换行策略是:当一个单词超出限制长度时,将它移动到下一行。有时这种策略并不合适。例如,在某些语言中,单词都比较长。如果采用这种策略,会出现每一行中只有一个单词。因此需要更改换行策略。当超出限制长度时,使用-作为一个分隔单词的标志。


换行策略调用

通过查看Cocos2d-x中换行的实现方式,我发现换行策略是区分平台编程出来的代码。也就是说,为了更改换行策略,我需要分别编写 IOS 和 Java 两部分代码。因为我的目标平台是 Android 平台,因此我只对Java文件进行了更改。IOS 平台的换行策略调用的是系统函数,有兴趣研究的读者可以跟踪源码更改。入口函数为:

  1. bool CCTexture2D::initWithString(const char *text,ccFontDefinition *textDefinition)
  2. {
  3. ......
  4. CCImage* pImage = new CCImage();
  5. do
  6. {
  7. CC_BREAK_IF(NULL == pImage);
  8. bRet = pImage->initWithStringShadowStroke(text,(int)textDefinition->m_dimensions.width,(int)textDefinition->m_dimensions.height,eAlign,textDefinition->m_fontName.c_str(),textDefinition->m_fontSize,textDefinition->m_fontFillColor.r / 255,textDefinition->m_fontFillColor.g / 255,textDefinition->m_fontFillColor.b / 255,shadowEnabled,shadowDX,shadowDY,shadowOpacity,shadowBlur,strokeEnabled,strokeColorR,strokeColorG,strokeColorB,strokeSize);
  9. CC_BREAK_IF(!bRet);
  10. bRet = initWithImage(pImage);
  11. } while (0);
  12. ......
  13. }

更改Java实现

Android 平台对应的 Java 文件位于 $(2DX-Root)/cocos2dx/platform/android/java/src/org/cocos2dx/lib 文件夹中,文件名是 Cocos2dxBitmap.java

首先,我增加了 divideStringWithMaxWidthByFlag 函数,将它作为另一个换行策略的实现函数

  1. // add by fansy for "—" style words
  2. private static LinkedList<String> divideStringWithMaxWidthByFlag(
  3. final String pString,final int pMaxWidth,final Paint pPaint) {
  4. final int charLength = pString.length();
  5. int start = 0;
  6. int tempWidth = 0;
  7. LinkedList<String> strList = new LinkedList<String>();
  8. if( !isChinese(pString) )
  9. {
  10. /* Break a String into String[] by the width & should wrap the word. */
  11. for (int i = 1; i < charLength-1; ++i) {
  12. tempWidth = (int) FloatMath.ceil(pPaint.measureText(pString,start,i+1));
  13. if (tempWidth >= pMaxWidth) {
  14. if(pString.charAt(i) == ' ') //end with " "
  15. {
  16. //change line at i
  17. strList.add(pString.substring(start,i));
  18. i = i + 1; // skip space
  19. }
  20. else if(i>1 && pString.charAt(i-2) == ' ') //only one "-" left after change line
  21. {
  22. //change line at i-2
  23. strList.add(pString.substring(start,i-2));
  24. i = i -2; // skip space
  25. }
  26. else if(i>0 && pString.charAt(i-1) == ' ') //only one "-" left after change line
  27. {
  28. //change line at i-1
  29. strList.add(pString.substring(start,i-1));
  30. i = i -1; // skip space
  31. }
  32. else if(i>0) //replace "-" at i-2
  33. {
  34. //split at i-1 add "-" at tail change line at i-1
  35. strList.add(pString.substring(start,i-1)+"-");
  36. i--;
  37. }
  38. /* Remove spaces at the beginning of a new line. */
  39. while (pString.charAt(i) == ' ') {
  40. ++i;
  41. }
  42. start = i;
  43. }
  44. }
  45. /* Add the last chars. */
  46. if (start < charLength) {
  47. strList.add(pString.substring(start));
  48. }
  49. }
  50. else
  51. {
  52. strList = divideStringWithMaxWidth(pString,pMaxWidth,pPaint);
  53. }
  54. return strList;
  55. }
  56. // 根据Unicode编码完美的判断中文汉字和符号
  57. private static boolean isChinese(char c) {
  58. Character.UnicodeBlock ub = Character.UnicodeBlock.of(c);
  59. if (ub == Character.UnicodeBlock.CJK_UNIFIED_IDEOGRAPHS
  60. || ub == Character.UnicodeBlock.CJK_COMPATIBILITY_IDEOGRAPHS
  61. || ub == Character.UnicodeBlock.CJK_UNIFIED_IDEOGRAPHS_EXTENSION_A
  62. || ub == Character.UnicodeBlock.CJK_UNIFIED_IDEOGRAPHS_EXTENSION_B
  63. || ub == Character.UnicodeBlock.CJK_SYMBOLS_AND_PUNCTUATION
  64. || ub == Character.UnicodeBlock.HALFWIDTH_AND_FULLWIDTH_FORMS
  65. || ub == Character.UnicodeBlock.GENERAL_PUNCTUATION) {
  66. return true;
  67. }
  68. return false;
  69. }
  70. // 完整的判断中文汉字和符号
  71. public static boolean isChinese(String strName) {
  72. char[] ch = strName.tocharArray();
  73. for (int i = 0; i < ch.length; i++) {
  74. char c = ch[i];
  75. if (isChinese(c)) {
  76. return true;
  77. }
  78. }
  79. return false;
  80. }
  81. //end add by fansy

增加函数之后,修改在 splitString 中的调用

  1. private static String[] splitString(final String pString,final int pMaxHeight,final Paint pPaint) {
  2. final String[] lines = pString.split("\\n");
  3. String[] ret = null;
  4. final FontMetricsInt fm = pPaint.getFontMetricsInt();
  5. final int heightPerLine = (int) Math.ceil(fm.bottom - fm.top);
  6. final int maxLines = pMaxHeight / heightPerLine;
  7. if (pMaxWidth != 0) {
  8. final LinkedList<String> strList = new LinkedList<String>();
  9. for (final String line : lines) {
  10. /*
  11. * The width of line is exceed maxWidth,should divide it into
  12. * two or more lines.
  13. */
  14. final int lineWidth = (int) FloatMath.ceil(pPaint
  15. .measureText(line));
  16. if (lineWidth > pMaxWidth) {
  17. strList.addAll(Cocos2dxBitmap.divideStringWithMaxWidthByFlag(
  18. line,pPaint));
  19. } else {
  20. strList.add(line);
  21. ......
  22. }

更换调用函数后,编译打包,运行程序即可看到不同的换行效果


本篇博客出自 阿修罗道 ,转载请注明出处,禁止用于商业用途: http://blog.csdn.net/fansongy/article/details/39992241

猜你在找的Cocos2d-x相关文章