cocos2dx3.2--字體標籤Label

轉自http://shahdza.blog.51cto.com/2410787/1560612


【嘮叨】

    在3.x中,廢棄了2.x裏的LabelTTFLabelAtlasLabelBMFont三個字體類,取而代之的是全新的字體標籤Label

    實際上Label是將三個字體類進行了融合,進行統一的管理與渲染,這使得創建字體標籤Label的方式更加統一,更加方便。

    本節來學習一下3.x中新的標籤類Label,如果對2.x中的三個字體類不瞭解的話,建議先去看看那三個類的用法,再來學習本節內容,能夠更好的理解。

    2.x中的舊標籤類,請移步:http://shahdza.blog.51cto.com/2410787/1541002


【致謝】

    http://cn.cocos2d-x.org/tutorial/show?id=1446

    http://www.cocoachina.com/bbs/read.php?tid=197179


【本節內容】

    在3.x中,Label支持四種方式的標籤創建。並新增了陰影Shadow、輪廓Outline、發光Glow效果的支持。還支持文字內容的行間距、文字間距、自動換行的設置。

    > 創建系統原生字體API : createWithSystemFont

    > 創建TTF             : createWithTTF       (原LabelTTF)

    > 創建CharMap         : createWithCharMap   (原LabelAtlas)

    > 創建BMFont          : createWithBMFont    (原LabelBMFont)


    > Label的屬性與方法

    > 文字效果渲染        : Shadow、Outline、Glow

    > 對齊方式            : TextHAlignment、TextVAlignment

    > Label的尺寸大小

    > 自動換行

    > 行間距、文字間距

    > 單獨設置某個字符


    關於圖片資源,請在cocos2dx給出的官方樣例cpp-tests中尋找。




【createWithSystemFont】

    創建系統原生字體的API。

    創建方式如下:

1
2
3
4
5
6
7
8
9
10
//
    static Label* createWithSystemFont(
        const std::string& text,                          //字符串內容
        const std::string& font,                          //字體(字體名稱、或字體文件)
        float fontSize,                                   //字號                           
        const Size& dimensions = Size::ZERO,              //label的尺寸大小,默認不設置尺寸
        TextHAlignment hAlignment = TextHAlignment::LEFT, //水平對齊方式,默認左對齊::LEFT
        TextVAlignment vAlignment = TextVAlignment::TOP   //垂直對齊方式,默認頂部  ::TOP
    );
//

    使用舉例:

1
2
3
4
//
    //使用系統的字體名稱 "Arial" 來創建
    Label* lb1 = Label::createWithSystemFont("123abc""Arial", 24);
//




【createWithTTF】

    創建TTF的方式有以下兩種:

    > 方式一:與2.x中LabelTTF的創建類似,不過使用的fontFile必須爲字體文件。

    > 方式二:通過TTF的配置信息數據結構TTFConfig來創建。


1、方式一:與System Font創建類似

    注:區別在於fontFile必須爲字體文件(如"*.ttf"),即不支持使用系統字體名稱來創建。

1
2
3
4
5
6
7
8
9
10
//
    static Label* createWithTTF(
        const std::string& text,
        const std::string& fontFile, //必須爲字體文件(如"*.ttf")
        float fontSize,
        const Size& dimensions = Size::ZERO,
        TextHAlignment hAlignment = TextHAlignment::LEFT,
        TextVAlignment vAlignment = TextVAlignment::TOP
    );
//


2、方式二:通過TTFConfig配置來創建


  2.1、TTFConfig配置

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
//
    typedef struct _ttfConfig 
    {
        std::string fontFilePath;  //字體文件路徑,如 "fonts/Arial.ttf"
        int fontSize;              //字體大小,默認"12"
        GlyphCollection glyphs;    //使用的字符集,默認"DYNAMIC"
        const char *customGlyphs;
        bool distanceFieldEnabled; //是否讓字體緊湊,默認false
        int outlineSize;           //字體輪廓大小,默認"0"
         
        //構造函數
        _ttfConfig(
            const char* filePath = "",
            int size = 12,
            const GlyphCollection& glyphCollection = GlyphCollection::DYNAMIC,
            const char *customGlyphCollection = nullptr,
            bool useDistanceField = false,
            int outline = 0
        );
    }TTFConfig;
//


  2.2、使用TTFConfig創建TTF

1
2
3
4
5
6
7
8
//
    static Label* createWithTTF(
        const TTFConfig& ttfConfig, //TTFConfig配置
        const std::string& text,    //字符串內容
        TextHAlignment alignment = TextHAlignment::LEFT,
        int maxLineWidth = 0        //最大文本行寬,0表示不設置。可用於自動換行只用
    );
//

    使用舉例:

1
2
3
4
5
6
7
8
9
10
11
12
//
    TTFConfig ttfConfig;
    ttfConfig.fontFilePath = "fonts/Marker Felt.ttf"//必須配置
    ttfConfig.fontSize = 12;
    ttfConfig.distanceFieldEnabled = false;
    ttfConfig.outlineSize = 0;
    ttfConfig.glyphs = GlyphCollection::DYNAMIC;
    ttfConfig.customGlyphs = nullptr;
     
    //使用TTFConfig配置,來創建TTF
    Label* lb3 = Label::createWithTTF(ttfConfig, "123abc");
//




【createWithCharMap】

    CharMap的用法與2.x中的LabelAtlas是一樣的,一般用來顯示數字。不過它也可以用來顯示其他字符,如英文字符。

    字體文件資源一般來自一張.png圖片,或.plist文件。

    注:圖片中每個字符的大小必須是固定的,若要改變字體大小,只能通過setScale放縮來實現。


    創建CharMap有三種方式:

        > 使用.png圖片創建

        > 使用紋理Texture2D創建

        > 使用.plist創建

    從圖片中從左到右,一塊一塊截取。從字符startCharMap開始一一對應。

    第一塊小圖片對應字符startCharMap;第二塊小圖片對應字符startCharMap+1;第三塊對應startCharMap+2 …… 以此類推。

    注:startCharMap爲ASCII碼,即:數字 '0' 爲48。

1
2
3
4
5
6
7
8
9
//
    //charMapFile  : 字符資源圖片png
    //itemWidth    : 每個字符的寬
    //itemHeight   : 每個字符的高
    //startCharMap : 圖片第一個是什麼字符
    static Label* createWithCharMap(const std::string& charMapFile, int itemWidth, int itemHeight, int startCharMap);
    static Label* createWithCharMap(Texture2D* texture, int itemWidth, int itemHeight, int startCharMap);
    static Label* createWithCharMap(const std::string& plistFile);
//


0、字符圖片資源

    digit.png:200*20(每個數字20*20)。

wKiom1Qvx-GgIeViAAAnr1bvdEA172.jpg


1、使用.png創建

1
2
3
4
5
//
    //create 字符圖片.png,每個字符寬,高,起始字符
    Label* lb4 = Label::createWithCharMap("fonts/digit.png", 20, 20, '0');
    lb4->setString("123456"); //設置字符串內容
//


2、使用Texture2D創建

    使用方法實際上與.png是類似的。

1
2
3
4
5
6
7
//
    //創建圖片紋理Texture2D
    Texture2D* texture = TextureCache::getInstance()->addImage("fonts/digit.png");
     
    Label* lb5 = Label::createWithCharMap(texture, 20, 20, '0');
    lb5->setString("123456"); //設置字符串內容
//


3、使用.plist創建

    在digit.plist裏需要配置:用到的字符圖片資源.png,每個字符的寬、高,起始字符。

    如下所示:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
//
    <?xml version="1.0" encoding="UTF-8"?>
    <!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
    <plist version="1.0">
    <dict>
        <key>version</key>           <!-- plist版本 -->
        <integer>1</integer>
        <key>textureFilename</key>   <!-- 字符圖片資源: digit.png -->
        <string>digit.png</string>
        <key>itemWidth</key>         <!-- 每個字符的寬: 20 -->
        <integer>20</integer>
        <key>itemHeight</key>        <!-- 每個字符的高: 20 -->
        <integer>20</integer>
        <key>firstChar</key>         <!-- 起始字符    : '0' -->
        <integer>48</integer>
    </dict>
    </plist>
//

    使用plist創建CharMap的方法:

1
2
3
4
5
//
    //plist的配置信息,如上所示
    Label* lb6 = Label::createWithCharMap("fonts/digit.plist");
    lb6->setString("123456");
//




【createWithBMFont】

    BMFont的用法與2.x中的LabelBMFont是一樣的。

    這個類使用之前,需要添加好字體文件,包括一個圖片文件(*.png)和一個字體座標文件(*.fnt),這兩個文件名稱必須一樣。可以下載一個fnt編輯工具來自定義字體。

    值得注意的是:

    > 在2.x中,可以使用 getChildByTag(i) 來獲取第i個字符,對其單獨設置屬性、動作等。

    > 在3.x中,則是使用 getLetter(i) ,而不再是 getChildByTag(i) 。

    這個類也沒辦法指定字體的字號大小,需要用setScale來縮放調整大小。

1
2
3
4
5
6
7
8
9
//
    static Label* createWithBMFont(
        const std::string& bmfontFilePath, //字體文件.font
        const std::string& text,           //內容
        const TextHAlignment& alignment = TextHAlignment::LEFT,
        int maxLineWidth = 0, 
        const Vec2& imageOffset = Vec2::ZERO       //字符圖片的起始左上角座標。一般不要設置這個參數,因爲座標的配置均已在.font裏完成
    );
//

    使用舉例:

1
2
3
//
    Label* lb7 = Label::createWithBMFont("bitmapFontTest.fnt""123abc", TextHAlignment::LEFT);
//




【Label的屬性與方法】

    Label繼承於:

    > SpriteBatchNode : 用於加快字體的渲染速度。

    > LabelProtocol   : 用於設置Label的字符串內容。


    主要函數如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
//
class CC_DLL Label : public SpriteBatchNode, public LabelProtocol
{
/**
 * 字體設置
 *     - setSystemFontName : 字體(字體名字、字體文件)
 *     - setSystemFontSize : 字體大小
 *     - setString         : 字符串內容
 *     - setTextColor      : 文字內容顏色
 **/
    //設置System Font類型的字體(字體名字、字體文件)
    //設置System Font類型的字體大小
    //請不要用於其他Label類型!(TTF、CharMap、BMFont)
    virtual void setSystemFontName(const std::string& systemFont);
    virtual void setSystemFontSize(float fontSize);
    virtual const std::string& getSystemFontName() const return _systemFont;}
    virtual float getSystemFontSize() const return _systemFontSize;}
 
 
    //改變字符串內容並重新渲染
    //注:如果你沒有爲Label設置TTF/BMFont/CharMap,會產生很大的開銷
    virtual void setString(const std::string& text) override;
    virtual const std::string& getString() const override {  return _originalUTF8String; }
 
 
    //設置文字顏色,僅支持TTF和System Font
    //注:區別 Node節點的顏色
    //      Node ::setColor     : Color3B
    //      Label::setTextColor : Color4B
    virtual void setTextColor(const Color4B &color);
    const Color4B& getTextColor() const return _textColor; }
 
 
/**
 * 獲取Label的某個字符
 *     - getLetter
 *     - 不支持System Font
 **/
    //不支持System Font
    virtual Sprite* getLetter(int lettetIndex);
 
 
/**
 * 文字渲染效果
 *     - Shadow  : 陰影
 *     - Outline : 輪廓,僅支持TTF
 *     - Glow    : 發光,僅支持TTF
 **/
    //陰影Shadow(陰影顏色,相對Label的偏移,模糊度)
    //注: 其中blurRadius在3.2中並未實現
    virtual void enableShadow(const Color4B& shadowColor = Color4B::BLACK,const Size &offset = Size(2,-2), int blurRadius = 0);
 
    //輪廓Outline,僅支持TTF(輪廓顏色,輪廓粗細)
    virtual void enableOutline(const Color4B& outlineColor,int outlineSize = -1);
 
    //發光Glow,僅支持TTF
    virtual void enableGlow(const Color4B& glowColor);
 
    //取消陰影/輪廓/發光渲染效果
    virtual void disableEffect();
 
 
/**
 * 對齊方式
 *    > TextHAlignment : 水平對齊方式
 *        - TextHAlignment:LEFT    : 左對齊
 *        - TextHAlignment:CENTER  : 居中對齊,默認
 *        - TextHAlignment:RIGHT   : 右對齊
 *    > TextVAlignment : 垂直對齊方式
 *        - TextVAlignment::TOP    : 頂部,默認
 *        - TextVAlignment::CENTER : 中心
 *        - TextVAlignment::BOTTOM : 底部
 **/
    //設置對齊方式
    void setAlignment(TextHAlignment hAlignment) { setAlignment(hAlignment,_vAlignment);}
    void setAlignment(TextHAlignment hAlignment,TextVAlignment vAlignment);
    TextHAlignment getTextAlignment() const return _hAlignment;}
 
    //設置水平對齊方式
    void setHorizontalAlignment(TextHAlignment hAlignment) { setAlignment(hAlignment,_vAlignment); }
    TextHAlignment getHorizontalAlignment() const return _hAlignment; }
 
    //設置垂直對齊方式
    void setVerticalAlignment(TextVAlignment vAlignment) { setAlignment(_hAlignment,vAlignment); }
    TextVAlignment getVerticalAlignment() const return _vAlignment; }
 
 
/**
 * Label尺寸大小
 *     - setLineBreakWithoutSpace : 開啓自動換行功能
 *     - setMaxLineWidth          : 文字內容的最大行寬
 *     - setWidth                 : Label尺寸大小,寬
 *     - setHeight                : Label尺寸大小,高
 *     - setDimensions            : Label尺寸大小
 **/
    //是否開啓自動換行功能
    void setLineBreakWithoutSpace(bool breakWithoutSpace);
 
 
    //最大行寬,內容超過MaxLineWidth,就會自動換行
    //前提條件: 僅在width==0時,起作用。
    //  > width == 0;
    //  > setMaxLineWidth(lineWidth);
    //  > setLineBreakWithoutSpace(true);
    //它的效果與下面是類似的.
    //  > setWidth(lineWidth);
    //  > setLineBreakWithoutSpace(true);
    //只是width==0時,就無法設置文本的對齊方式了.
    void setMaxLineWidth(unsigned int maxLineWidth);
    unsigned int getMaxLineWidth() { return _maxLineWidth;}
 
 
    //設置Label的尺寸大小
    //可以理解爲Label的文本框大小
    //當setLineBreakWithoutSpace(true)時,內容超過width,會自動換行
    //並且內容支持文本的對齊方式
    //注:設置尺寸大小,使用的是setDimensions,而不是setContentSize !
    void setWidth(unsigned int width) { setDimensions(width,_labelHeight); }
    void setHeight(unsigned int height){ setDimensions(_labelWidth,height); }
    void setDimensions(unsigned int width,unsigned int height);
    unsigned int getWidth() const return _labelWidth; }
    unsigned int getHeight() const return _labelHeight; }  
    const Size& getDimensions() constreturn _labelDimensions; }
 
 
/**
 * v3.2 新增
 *     - setLineHeight        : 設置行間距
 *     - setAdditionalKerning : 設置文字間距
 *     - getStringLength      : 字符串內容長度
 */
    //設置行間距,不支持system font
    void setLineHeight(float height);
    float getLineHeight() const;
 
    //設置文字間距,不支持system font
    void setAdditionalKerning(float space);
    float getAdditionalKerning() const;
 
    //獲取Label的字符串內容長度
    int getStringLength() const;
 
 
/**
 * 重寫Node父類的方法
 *     - setBlendFunc   : 混合模式
 *     - setScale       : 放縮字體大小
 *     - addChild       : 添加子節點
 *     - getDescription : 顯示Label的描述
 **/
    //設置顏色混合模式
    virtual void setBlendFunc(const BlendFunc &blendFunc) override;
 
    //放縮字體大小(一般用於CharMap、BMFont)
    virtual void setScale(float scale) override;
    virtual void setScaleX(float scaleX) override;
    virtual void setScaleY(float scaleY) override;
    virtual float getScaleX() const override;
    virtual float getScaleY() const override;
 
    //添加子節點
    virtual void addChild(Node * child, int zOrder=0, int tag=0) override;
    virtual void sortAllChildren() override;
 
    //Label描述
    virtual std::string getDescription() const override;
};
//




【文字渲染效果】

    支持三種渲染效果:

    > Shadow  : 陰影

    > Outline : 輪廓,僅支持TTF

    > Glow    : 發光,僅支持TTF

    注:其中Outline與Glow兩個效果,只會作用一個。即無法一起使用。

    

    使用舉例:

1
2
3
4
5
6
7
8
9
10
11
12
//
    Label* lb = Label::createWithTTF("123abc""fonts/Marker Felt.ttf", 50);
    lb->setPosition(visibleSize / 2);
    this->addChild(lb);
 
    lb->enableShadow(Color4B::GREEN, Size(10, 10)); //陰影
    lb->enableOutline(Color4B::RED, 3);             //輪廓
    //lb->enableGlow(Color4B::GREEN);                 //發光
 
    //取消陰影、輪廓、發光效果
    //lb->disableEffect();
//

    如圖所示:

wKioL1Qvv4HyUNY-AABCHrs_f5E221.jpg


wKiom1Qvv0-juVHmAABDu6Gdx6s457.jpg


wKioL1Qvv4HQG4l9AABKGsut21I226.jpg




【對齊方式】

    > TextHAlignment : 水平對齊方式

        - TextHAlignment:LEFT    : 左對齊

        - TextHAlignment:CENTER  : 居中對齊,默認

        - TextHAlignment:RIGHT   : 右對齊

    > TextVAlignment : 垂直對齊方式

        - TextVAlignment::TOP    : 頂部,默認

        - TextVAlignment::CENTER : 中心

        - TextVAlignment::BOTTOM : 底部

    僅在設置了Label的尺寸大小setDimensions(width,height),大於顯示的字符串內容的尺寸大小,纔會起作用。

    對齊方式舉例,如下幾張圖片所示:

    對齊方式爲:

        TextHAlignment:LEFT

        TextVAlignment::TOP

wKioL1Qvt1bAd5pCAAC6gJHn1rI260.jpg


wKioL1Qvt1bT5tb1AADDFNsBpXs376.jpg


wKiom1QvtyTCyKw7AADIdMaUl50455.jpg




【自動換行】

    在3.x中,自動換行有兩種方式。(當然你也可以使用C++裏的轉移字符'\n'進行手動換行)

    > 利用lb->setLineBreakWithoutSpace(true),來支持自動換行功能。

    > 1. 利用 setMaxLineWidth(maxLineWidth),來控制自動換行。

    > 2. 利用 setDimensions(width , height),來控制自動換行。


1、利用setMaxLineWidth

    設置每行顯示文字的最大寬度。

    注:這種方法僅在Label width == 0的情況下,纔會有效。

    使用方法:

1
2
3
4
//
    lb->setLineBreakWithoutSpace(true);
    lb->setMaxLineWidth(120); //最大寬度120
//

    如圖:

wKioL1QvuCbx2CuJAACnIfYPH8o016.jpg


2、利用setDimensions

    使用方法:

1
2
3
4
5
//
    lb->setLineBreakWithoutSpace(true);
    lb->setWidth(80);         //設置Label尺寸寬80
    lb->setMaxLineWidth(120); //設置了Label width,這個就無效了
//

    如圖:

wKiom1QvuAKSA95FAAConOTfXF0856.jpg




【文字間距】

    間距的調整,是在 v3.2 之後纔出現的。可以設置文本內容的行間距與文字間距。

    注:不支持System Font。

    > setLineHeight        : 設置行間距

    > setAdditionalKerning : 設置額外文字間距


    使用舉例:

1
2
3
4
//
    lb->setLineHeight(80);
    lb->setAdditionalKerning(10);
//

    圖解:

wKiom1QvvLuCSN8WAADoNwsARbo883.jpg




【單獨設置某個字符】

    學過2.x中的LabelBMFont的同學,應該知道這個是怎麼回事吧?

    在3.x中,使用TTFCharMapBMFont創建的文字標籤,其字符串內容的每個字符都是一個Sprite精靈圖片,可以對其進行單獨的設置。如精靈放縮、執行動作等。

    注:不支持System Font。

    > lb->getStringLength() : 獲取字符串內容的總長度

    > lb->getLetter(i)      : 獲取第i個位置上的字符


    使用舉例:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
//
    Label* lb = Label::createWithTTF("123abc""fonts/Marker Felt.ttf", 50);
    lb->setPosition(visibleSize / 2);
    this->addChild(lb);
 
    //獲取字符串總長度,length = 6
    CCLOG("%d", lb->getStringLength());
 
    //獲取第1個字符
    Sprite* letter1 = lb->getLetter(1);
    letter1->setColor(Color3B::GREEN); //設置顏色
    letter1->setScale(2.0f);           //放縮
 
    //獲取第4個字符
    Sprite* letter4 = lb->getLetter(4);
    letter4->setColor(Color3B::RED);  //設置顏色
    letter4->runAction(RepeatForever::create(RotateBy::create(1.0f, 90))); //執行旋轉動作
//

    如圖:

wKiom1Qvw-uiM3moAAPOzv2Anc4744.gif


發佈了34 篇原創文章 · 獲贊 5 · 訪問量 6萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章