cocos2dx-标签:Label的使用

一、setContentSize与setDimensions对于Label的作用

1、首先看看setContentSize的定义:

/*
* Set the untransformed size of the node.
* 设置节点转换前的大小
* The contentSize remiains the same no matter the node is scaled or rotated.
* 无论缩放还是旋转节点,它的contentSize始终保持不变
* All nodes has a size. Layer and Scene has the same size of the screen.
* 所有的节点都有一个大小,layer和scene的大小和屏幕大小保持一致
*/

/*
* 说明:
* 1、节点在使用的过程中可能进行缩放、旋转等变化,这样导致我们看见的节点的大小可能发生了变化。但是
* contentSize是一直保持
* 不变的,因为这是一个基准。可以想一下,如果这个contentSize在进行缩放之后发生了变化,那么在
* setScale(1.5f)之后再设置setScale(1.0f)如何能够还原呢?
*/

void Node::setContentSize(const Size& size)
{
    if(!size.equals(_contentSize)
    {   
        _contentSize = size;
        _anchorPoints.set(_contentSize.width * _anchorPoint.x, _contentSize.height * _anchorPoint.y);
        _transformUpdated= _transformDiry = _inverseDirty = _contentSizeiryt = true;
    }
}

2、其次,我们看看setDimenSions的定义:

/*
Sets the untransformed size of the Label in a more efficient way.
以一种更高效的方式设置Label未转换前的大小
*/

void Label::setDimensions(float width, float height)
{
    if(_overflow == Overflow::RESIZE_HEIGHT){
        height = 0;
    }
    if (height != _labelHeight || width != _labelWidth)
    {
        _labelWidth = width;
        _labelHeight = height;
        _labelDimensions.width = width;
        _labelDimensions.height = height;

        _maxLineWidth = width;
        _contentDirty = true;

        if(_overflow == Overflow::SHRINK){
            if (_originalFontSize > 0) {
                this->restoreFontSize();
            }
        }
    }
}

3、_labelDimensions、_labelWidth、_labelHeight的使用:

        在setDimensions的源码中我们看到了主要是对这几个成员变量进行了设置,那么这几个成员变量的使用方法以及相关的作用是什么呢?首先来看看_labelDimensions的使用:

cocos2dx-标签:Label的使用_第1张图片

         从上图中可以知道,对于_labelDimensions成员变量的使用只在相关的set和get方法中出现了。接下来我们看看_labelWidth和_labelHeight的使用。

        cocos2dx-标签:Label的使用_第2张图片

        从上图中我们可以看到,在alignText方法中使用到了_labelWidth,即在文字的对齐方式中进行了使用。因此我们很自然的可以想到:_labelDimenSions与标签的对齐方式有关。其中setMaxLineWidth也说明了,只有在调用了setDimenSions方法之后,对于标签的对齐方式、显示方式才会生效。 

4、实验验证:

auto labTest = Label::createWithSystmeFont("I love China, I am a Chinese", "", 30);
labTetst->setPosition(Vec2(_size.width / 2, _size.height * 0.75f));
this->addChild(labTest, 100);

auto labTest2 = Label::createWithSystemFont("I love China, I am a Chinese", "", 30);
labTest2->setPosition(Vec2(m_vSize.width / 2, m_vSize.height * 0.70));
labTest2->setDimensions(200.0f, 80.0f);
this->addChild(labTest2, 100);

auto labTest3 = Label::createWithSystemFont("I love China, I am a Chinese", "", 30);
labTest3->setPosition(Vec2(m_vSize.width / 2, m_vSize.height * 0.65));
labTest3->setContentSize(Size(200.0f, 80.0f));
this->addChild(labTest3, 100);

cocos2dx-标签:Label的使用_第3张图片

        由上述的实验结果我们可以看到,分别使用setDimenSions和setContentSize方法对于Label进行同样大小的设置,但是setContentSize并没有起到什么效果;而使用setDimenSions对Label的设置产生了效果,同时使其进行了自动缩放和换行的调整。

5、结论:

  1. setContentSize和setDimenSions都是设置节点大小,但是对于Label而言,setContentSize并没有什么作用,而是通过使用setDimenSions来进行相关的设置。

  2. 对于Label进行对齐方式、换行等设置也只有在调用了setDimenSions之后才会生效。  

二、 Label常用操作封装

1、Label设置下划线:

        在公司做产品的过程中遇到这样一个使用场景,需要对Label创建的字体加上一个下划线,但是又没有现成的接口可以设置下划线于是就自己封装了一个。

// Label增加下划线处理
void whStartLayer::labAttachUnderline(Label* labNode)
{
	if (nullptr == labNode) {
		return;
	}

	float labWidth = labNode->getContentSize().width;
	auto underLine = DrawNode::create();
	underLine->drawSegment(Vec2(0, 0), Vec2(labWidth, 0), 1, Color4F::BLACK);
	labNode->addChild(underLine);

	return;
}

示例1:

// 创建一个label
auto labPrivacy = Label::createWithSystemFont(u8"隐私协议", "", 40.0f);
labPrivacy->setTextColor(Color4B(0x2e, 0x2e, 0x2e, 0xff));
labPrivacy->setPosition(Vec2(visibleSize / 2));
this->addChild(labPrivacy);
// label增加下划线处理
labAttachUnderline(labPrivacy);

2、Label文本过长的处理方式

        目前我在游戏开发的过程中经常会遇见文本内容过长的问题,我个人对于此类问题的处理主要是采用以下两种方式:1,设置label的最大宽度,不进行换行操作,当文本大小超过了最大宽度限定就会进行自动缩放;2,设置label的最大宽度,同时保持字体大小不变,超过最大限度之后之后进行换行处理。

        对于第一种处理方式主要适用于标题、按钮文本等内容的处理,文本必须在一行呈现出来才比较美观。

// 标签内容一行呈现,字体进行自动缩放
void setLabAlignInOneLine(Label* labNode, float maxWidth)
{
	auto curSize = labNode->getContentSize();
	float dimenWidth = curSize.width > maxWidth ? maxWidth : curSize.width;
	labNode->setDimensions(dimenWidth, curSize.height);
	labNode->setOverflow(Label::Overflow::SHRINK);	// 设置溢出处理方式(共有4种):缩放处理
	labNode->setAlignment(TextHAlignment::CENTER, TextVAlignment::CENTER);
	return;
}

        对于第二种方式,我们保持字体的大小不变,在最大宽度限定下来自动适应高度。其实Label中的溢出处理方式中有一个“Label::Overflow::RESIZE_HEIGHT”,但是设置这个属性之后去获取标签的大小时,高度始终时0,因为这个bug我就放弃了这种处理方式。因为我在使用的过程中还是需要Label的大小去设置相应的位置坐标,因此我采用以下的方式进行处理。

        使用过程中自己去判断为了保持字体大小不变,最大宽度限定下实际创建的Label会有多少行,然后手动去设定标签的大小。如果不手动设置标签大小的话,换行之后的部分文本可能无法显示出来。

void setLabAutoHeight(Label * labNode, float maxWidth, TextHAlignment hType, TextVAlignment vType, float lineSpace)
{
    auto curSize = labNode->getContentSize();
    int lineNum = (int)(curSize.width / maxWidth) + 1;
    float dimenHeight = lineNum*(curSize.height + lineSpace) - lineSpace;
    labNode->setDimensions(maxWidth, dimenHeight);
    labNode->setAlignment(hType, vType);
    labNode->setLineBreakWithoutSpace(true);
    labNode->setLineSpacing(lineSpace);
    
    return;
}

示例2:

// 示例代码:
	string textStr = u8"这是一个标题示例,我们正在做溢出处理测试。";
	auto labTemp = Label::createWithSystemFont(textStr, "", 40.0f);
	labTemp->setPosition(Vec2(visibleSize.width / 2, 1000.0f));
	labTemp->setTextColor(Color4B::BLACK);
	this->addChild(labTemp);

	auto labTemp2 = Label::createWithSystemFont(textStr, "", 40.0f);
	labTemp2->setPosition(Vec2(visibleSize.width / 2, 900.0f));
	labTemp2->setTextColor(Color4B::BLACK);
	this->addChild(labTemp2);
	setLabAlignInOneLine(labTemp2, 600.0f);

   cocos2dx-标签:Label的使用_第4张图片

示例3:

// 示例代码:

    // 文本内容一行展示
	string textStr = u8"这是一个标题示例,我们正在做溢出处理测试。再继续增加一点文字长度!";
	auto labTemp = Label::createWithSystemFont(textStr, "", 40.0f);
	labTemp->setPosition(Vec2(visibleSize.width / 2, 900.0f));
	labTemp->setTextColor(Color4B::BLACK);
	this->addChild(labTemp);

	// 水平居中对齐
	auto labTemp2 = Label::createWithSystemFont(textStr, "", 40.0f);
	labTemp2->setPosition(Vec2(visibleSize.width / 2, 700.0f));
	labTemp2->setTextColor(Color4B::BLACK);
	this->addChild(labTemp2);
	setLabAutoHeight(labTemp2, 600.0f, TextHAlignment::CENTER, TextVAlignment::CENTER, 0.0f);	

	// 水平左对齐
	auto labTemp3 = Label::createWithSystemFont(textStr, "", 40.0f);
	labTemp3->setPosition(Vec2(visibleSize.width / 2, 500.0f));
	labTemp3->setTextColor(Color4B::BLACK);
	this->addChild(labTemp3);
	setLabAutoHeight(labTemp3, 600.0f, TextHAlignment::LEFT, TextVAlignment::CENTER, 0.0f);	

	// 水平右对齐
	auto labTemp4 = Label::createWithSystemFont(textStr, "", 40.0f);
	labTemp4->setPosition(Vec2(visibleSize.width / 2, 300.0f));
	labTemp4->setTextColor(Color4B::BLACK);
	this->addChild(labTemp4);
	setLabAutoHeight(labTemp4, 600.0f, TextHAlignment::RIGHT, TextVAlignment::CENTER, 0.0f);	

 cocos2dx-标签:Label的使用_第5张图片

三、Label常用接口说明:

  1. setLineBreakWithoutSpace();
    指定当一行太长的时候对于标签来说会发生什么,该行会在单词之间自动进行断开换行,即标签太长而换行的时候不会将一个完成的单词一分为二。
  2. setMaxLineWith();
    使标签最多不超过该行的未转换宽度,如果该值不为零,则标签的最大线宽将用于强制换行。即限制标签的最大宽度,如果超出之后会进行换行处理。
  3. setDimensions();
    设置标签的大小,前面已经说过了,只要设置了标签的大小之后对于标签的自动换行、缩放、对齐方式等的设置才会有意义。
  4. setOverflow();
    设置标签的移除处理方式,主要有四种处理方式:自动适应、超出区域被裁剪、自动缩放、自动适应高度的方式。
  5. setAlignment();
    设置标签的对其方式,横向、纵向
  6. setLineSpacing();
    设置标签的行距,不支持系统字体

​​​​​​​​​​​​​​​​​​​​​

你可能感兴趣的:(cocos2dx,cocos2d,c++)