Cocos2dx change line
在 cocos2dx change line 的实现中,我们可以简单的使用dimensions
属性控制换行。使用它只需将对应的参数值传入构造函数,或者调用 setDimensions 函数即可。
它的换行策略是:当一个单词超出限制长度时,将它移动到下一行。有时这种策略并不合适。例如,在某些语言中,单词都比较长。如果采用这种策略,会出现每一行中只有一个单词。因此需要更改换行策略。当超出限制长度时,使用-
作为一个分隔单词的标志。
换行策略调用
通过查看Cocos2d-x中换行的实现方式,我发现换行策略是区分平台编程出来的代码。也就是说,为了更改换行策略,我需要分别编写 IOS 和 Java 两部分代码。因为我的目标平台是 Android 平台,因此我只对Java文件进行了更改。IOS 平台的换行策略调用的是系统函数,有兴趣研究的读者可以跟踪源码更改。入口函数为:bool CCTexture2D::initWithString(const char *text,ccFontDefinition *textDefinition) { ...... CCImage* pImage = new CCImage(); do { CC_BREAK_IF(NULL == pImage); 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); CC_BREAK_IF(!bRet); bRet = initWithImage(pImage); } while (0); ...... }
更改Java实现
Android 平台对应的 Java 文件位于 $(2DX-Root)/cocos2dx/platform/android/java/src/org/cocos2dx/lib 文件夹中,文件名是 Cocos2dxBitmap.java
首先,我增加了 divideStringWithMaxWidthByFlag 函数,将它作为另一个换行策略的实现函数。
// add by fansy for "—" style words private static LinkedList<String> divideStringWithMaxWidthByFlag( final String pString,final int pMaxWidth,final Paint pPaint) { final int charLength = pString.length(); int start = 0; int tempWidth = 0; LinkedList<String> strList = new LinkedList<String>(); if( !isChinese(pString) ) { /* Break a String into String[] by the width & should wrap the word. */ for (int i = 1; i < charLength-1; ++i) { tempWidth = (int) FloatMath.ceil(pPaint.measureText(pString,start,i+1)); if (tempWidth >= pMaxWidth) { if(pString.charAt(i) == ' ') //end with " " { //change line at i strList.add(pString.substring(start,i)); i = i + 1; // skip space } else if(i>1 && pString.charAt(i-2) == ' ') //only one "-" left after change line { //change line at i-2 strList.add(pString.substring(start,i-2)); i = i -2; // skip space } else if(i>0 && pString.charAt(i-1) == ' ') //only one "-" left after change line { //change line at i-1 strList.add(pString.substring(start,i-1)); i = i -1; // skip space } else if(i>0) //replace "-" at i-2 { //split at i-1 add "-" at tail change line at i-1 strList.add(pString.substring(start,i-1)+"-"); i--; } /* Remove spaces at the beginning of a new line. */ while (pString.charAt(i) == ' ') { ++i; } start = i; } } /* Add the last chars. */ if (start < charLength) { strList.add(pString.substring(start)); } } else { strList = divideStringWithMaxWidth(pString,pMaxWidth,pPaint); } return strList; } // 根据Unicode编码完美的判断中文汉字和符号 private static boolean isChinese(char c) { Character.UnicodeBlock ub = Character.UnicodeBlock.of(c); if (ub == Character.UnicodeBlock.CJK_UNIFIED_IDEOGRAPHS || ub == Character.UnicodeBlock.CJK_COMPATIBILITY_IDEOGRAPHS || ub == Character.UnicodeBlock.CJK_UNIFIED_IDEOGRAPHS_EXTENSION_A || ub == Character.UnicodeBlock.CJK_UNIFIED_IDEOGRAPHS_EXTENSION_B || ub == Character.UnicodeBlock.CJK_SYMBOLS_AND_PUNCTUATION || ub == Character.UnicodeBlock.HALFWIDTH_AND_FULLWIDTH_FORMS || ub == Character.UnicodeBlock.GENERAL_PUNCTUATION) { return true; } return false; } // 完整的判断中文汉字和符号 public static boolean isChinese(String strName) { char[] ch = strName.tocharArray(); for (int i = 0; i < ch.length; i++) { char c = ch[i]; if (isChinese(c)) { return true; } } return false; } //end add by fansy
private static String[] splitString(final String pString,final int pMaxHeight,final Paint pPaint) { final String[] lines = pString.split("\\n"); String[] ret = null; final FontMetricsInt fm = pPaint.getFontMetricsInt(); final int heightPerLine = (int) Math.ceil(fm.bottom - fm.top); final int maxLines = pMaxHeight / heightPerLine; if (pMaxWidth != 0) { final LinkedList<String> strList = new LinkedList<String>(); for (final String line : lines) { /* * The width of line is exceed maxWidth,should divide it into * two or more lines. */ final int lineWidth = (int) FloatMath.ceil(pPaint .measureText(line)); if (lineWidth > pMaxWidth) { strList.addAll(Cocos2dxBitmap.divideStringWithMaxWidthByFlag( line,pPaint)); } else { strList.add(line); ...... }
更换调用函数后,编译打包,运行程序即可看到不同的换行效果。
本篇博客出自 阿修罗道 ,转载请注明出处,禁止用于商业用途: http://blog.csdn.net/fansongy/article/details/39992241 原文链接:https://www.f2er.com/cocos2dx/347035.html