【CC2DX随笔】中文显示及文字标签位置排版

中文显示及文字标签位置排版

效果图

中文显示

在cocos2dx里用label去显示文字,label读取文字时,是用的UTF-8的编码去读取。

读取中文的时候有多种方法,比如做编码转换,用iconv,或者用第三文件读取(xml或者json等),我这里使用的是xml。

使用xml的原因是比较方便简单,也容易做多语言的读取转换。

配置xml

在配置xml时,需要将xml文件修改为UTF-8编码。用固定xml格式,如下。

<?xml version="1.0" encoding="UTF-8"?>
<plist version="1.0">
    <dict>
        <key>DollRepairTitle</key>
        <string>轮回的西藏人形</string>
        <key>DollRepairMainDesc</key>
        <string>人偶在濒死状态时,恢复100%生命,在2秒内持续衰减至0。</string>
        <key>DollRepairSubDesc</key>
        <string>无论如何,这家伙还是挺有一套的。</string>
        
        <key>DollStrengthemTitle</key>
        <string>魔彩光的上海人型</string>
        <key>DollStrengthemMainDesc</key>
        <string>强化人偶的肢体,提高防御力。</string>
        <key>DollStrengthemSubDesc</key>
        <string>她原本应该有能力使用那些非常强有力的魔法。</string>
    </dict>
</plist>

读取文字

在 3.0 或一些旧版本的时候,使用的是Dictionary::createWithContentsOfFile("something.xml");objectForKey();

但在新版本中,改用新的API: ValueMap pTextMap = FileUtils::getInstance()->getValueMapFromFile(cszpXml);
声明初始化一个kv map表,在读取的时候用中括号读取并转换成需要的字符串。

/* 示例. */
const char* cszpXml = "data\\String\\string_skillDesc.xml";
char szarrTmpRet[THMAX_CHAR_DESC] = { 0 };
ValueMap pTextMap = FileUtils::getInstance()->getValueMapFromFile(cszpXml);
std::string strRet = "";

sprintf_s(szarrTmpRet, THMAX_CHAR_DESC, "%sTitle", cszpSk);
strRet = pTextMap[szarrTmpRet].asString();
const char* cszpTitle = strRet.c_str();
strcpy_s(szpTitleRet, THMAX_CHAR_DESC, cszpTitle);

这样就完成了对中文的读取。

FileUtils在读取的时候默认是去Resources目录下搜寻,不需要再手动添加Resources路径,哪怕修改了程序运行路径,只需要保证程序运行路径下有Resources目录及对应的目录。
如果搜不到这个文件时,Ouput窗口会有CCLOG报出的错误,需要多注意观察。

需要注意的点

在读取中文的时候,因为VS2019的编码不是UTF-8是unicode,所以在debug控制台或者直接CCLOG打印时,会出现读取不到中文的情况。

如果将XML文件修改至ANSI编码,VS能够正常识别出中文,但此时cocos2dx的Label组件无法识别这个文字!会在渲染时直接不显示这个文字!
在渲染中文时,xml的文件一定为UTF8编码。

文字标签排版

/* 一些自定义的宏. */

/* 获取精灵的底部Y值. */
#define TH_GETBOTTOMY(p) ( p->getPositionY() - p->getBoundingBox().size.height * p->getAnchorPoint().y )
/* 获取精灵的顶部Y值. */
#define TH_GETTOPY(p) ( p->getPositionY() + p->getBoundingBox().size.height * p->getAnchorPoint().y )
/* 创建文字Label标签,并设置基础属性. */
#define TH_CREATE_CN_LABELTEXT(p, str, size, tColor, fPosX, fPosY, bVis, emAli, nWidth)	\
do																						\
{																						\
	p = Label::createWithTTF(str, "fonts\\FZKai.ttf", size);							\
	TH_PROCESS_ERROR(p);																\
	p->setColor(tColor);																\
	p->setPosition(fPosX, fPosY);														\
	p->setVisible(bVis);																\
	p->setWidth(nWidth);																\
	p->setAlignment(emAli);																\
} while (0);

排版

默认的label标签的锚点都在中间(0.5,0.5),如果想实现一行文字接着另外一行文字显示(一个label接着另外一个label),就要将锚点改为中间上部(0.5,1)。这样就不会所有标签全部堆积在一起。

通常第一个label标签的位置都可以任意定位,第二个label标签紧接着第一个label的话,就要计算第一个label标签的底部Y值,第一个label标签的底部Y值 = 第二个label标签的顶部Y值。

自动换行设置label长度即可: pLb->setWidth(f);

/* 示例. */
/* 文字主介绍. */
tFontMainColor.r = 240;
tFontMainColor.g = 230;
tFontMainColor.b = 185;
fTextY = TH_GETBOTTOMY(pTmpSkText->pLbTitleText) - 5;
TH_CREATE_CN_LABELTEXT(
	pTmpSkText->pLbMainDesc, szarrMainTextDesc, 19, tFontMainColor, fPoxX, 
	fTextY, THFALSE, TextHAlignment::LEFT, fTextLabelWidth
);
pTmpSkText->pLbMainDesc->setAnchorPoint(Vec2(0.5, 1));

posted @ 2024-06-14 16:37  阿初  阅读(8)  评论(0编辑  收藏  举报