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

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

添加函数之后。改动在 splitString 中的调用:

private static String[] splitString(final String pString,
            final int pMaxWidth, 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, pMaxWidth, pPaint));
                } else {
                    strList.add(line);
        ......
}

更换调用函数后,编译打包。执行程序就可以看到不同的换行效果。本篇博客出自阿修罗道,转载请注明出处,禁止用于商业用途:http://blog.csdn.net/fansongy/article/details/39992241

时间: 2024-10-21 00:52:59

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

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

Cocos2dx change line 在 cocos2dx change line 的实现中,我们可以简单的使用 dimensions属性控制换行.使用它只需将对应的参数值传入构造函数,或者调用 setDimensions 函数即可. 它的换行策略是:当一个单词超出限制长度时,将它移动到下一行.有时这种策略并不合适.例如,在某些语言中,单词都比较长.如果采用这种策略,会出现每一行中只有一个单词.因此需要更改换行策略.当超出限制长度时,使用 - 作为一个分隔单词的标志. 换行策略调用 通过查看

代码风格——Cocos2d-x学习历程(四)

1.Cocos2d-x拥有一个包含其他所有头文件的文件"cocos2d.h".通常,我们只需要在使用时包含这个头文件,就可以使用引擎的全部功能了. 2.Cocos2d-x的类都放置于cocos2d命名空间下.在游戏中,我们常使用引擎提供的另一个宏USING_NS_CC来引用cocos2d命名空间: #define USING_NS_CC using namespace cocos2d. 3.类的命名与Cocos2d-iPhone一致,由类库缩写加上类名称组成,其中类库缩写采用大写,类名

【Cocos2d入门教程一】Cocos2d-x环境搭建

在进行Cocos2d游戏开发前 我们先来配置一下环境,我们先来准备一下工具,我们所需要的工具分别为: 1.Cocos2d引擎 2.JDK 3.SDK 4.NDK 5.ANT 6.ADT 1.下载Cocos2d-x引擎,目前最新版本为3.6,本教程的所有例子以3.4版本为例,下载完直接解压即可.点击下载Cocos2d引擎 2.JDK 检查自己电脑上是否已装好JDK环境 方法:打开终端,输入 java–version 如果没有安装过,点击下载JDK 效果如下: 3.ADT下载,ADT被称为安卓的集成

【Cocos2d入门教程二】Cocos2d-x基础篇

上一章已经学习了环境的搭建.这一章对基础概念进行掌握.内容大概有: 1.导演 2.场景 3.节点 4.层 4.精灵 1.导演(Director) 导演存在的主要作用: 环境设定(帧率 初始化openGl和渲染器) 场景管理 执行主循环 游戏就是个死循环 不断不断的渲染  就跟视频没两样 一帧一帧的绘制出来  话说提一下一帧为1/60秒  也就是说cocos2d里一秒渲染60次 导演的管理:   计时器  事件管理器  动作管理器 导演继承于REF  一个单例类 获得导演类Director实例语句

【Cocos2d入门教程五】Cocos2d-x动作篇

动作类(Action)是所有动作的基类,它创建的一个对象代表一个动作.动作作用于Node,包括继承于之下的Layer.Sprite.因此每个动作 都需要由Node对象或者其继承者执行.动作类(Action)作为基类,实际上是一个接口,动作类的大多数实现类都派生于有限时间动作类 (FiniteTimeAction).其关系图如下: 在实际开发中我们通常用到两类动作-即时动作和持续动作,它们均继承于有限时间动作类. 1. 即时动作 放置–Place 隐藏– Hide 显示– Show 可见切换–To

【Cocos2d入门教程四】Cocos2d-x菜单篇

游戏世界多姿多彩,无论多靓丽的游戏,多耐玩的游戏,在与游戏用户交互上的往往是菜单. 上一章我们已经大概了解了导演.节点.层.精灵.这一章以菜单为主题. 菜单(Menu)包含以下内容: 1.精灵菜单项(MenuItemSprite) 2.图片菜单项(MenuItemImage) 3.文字菜单项(MenuItemFont) 4.标签菜单项(MenuItemLabel) 4.开关菜单项(MenuItemToggle) 菜单的继承关系: 这里图片菜单项也是同样继承于精灵菜单下.图片菜单项也可称为精灵菜单

【Cocos2d入门教程六】Cocos2d-x事件篇之触摸

Cocos游戏当中产生一个事件时,可以有多个对象在监听该事件,所以有优先级(Priority).优先级越高(Priority值越小),事件响应越靠前. 关系图: 新 事件分发机制:在2.x 版本事件处理时,将要触发的事件交给代理(delegate)处理,再通过实现代理里面的onTouchBegan等方法接收事件,最后完成事件的响应. 而在新的事件分发机制(3.x)中,只需通过创建一个事件监听器-用来实现各种触发后的逻辑,然后添加到事件分发器_eventDispatcher,所 有事件监听器由这个

【Cocos2d入门教程二】Cocos2d-x基础概念

上一章已经学习了环境的搭建.这一章对基础概念进行掌握.内容大概有: 1.导演 2.场景 3.节点 4.层 4.精灵 1.导演(Director) 导演存在的主要作用: 环境设定(帧率 初始化openGl和渲染器) 场景管理 执行主循环 游戏就是个死循环 不断不断的渲染  就跟视频没两样 一帧一帧的绘制出来  话说提一下一帧为1/60秒  也就是说coco里一秒渲染60次 导演的管理:   计时器  事件管理器  动作管理器 导演继承于REF  一个单例类 获得导演类Director实例语句 au

Cocos2d-x3.0模版容器详解之三:cocos2d::Value

1.概述 版本: v3.0 beta 语言: C++ 定义在 "COCOS2DX_ROOT/cocos/base" 路径下的 "CCValue.h" 的头文件中. ? 1 class Value; cocos2d::Valie 是一个包含了很多原生类型(int,float,double,bool,unsigned char,char* 和 std::string)外加 std::vector<Value>, std::unordered_map<s