字体的实现方式
free type
Free type 字体,例如 ttf 格式的字体。不同于位图字体使用像素来表示字体,Free type 字体只是定义了字体的渲染数据,需要在运行时实时计算然后渲染。这样的字体就不存在放缩问题,但需要一定的计算消耗。
CCLabelTTF
先说 LabelTTF , TTF(TrueType Font) 是一种字库规范,是 Apple 公司和 Microsoft 公司共同推出的字体文件格式,随着windows的流行,已经变成最常用的一种字体文件表示方式。
-
优点:CCLabelTTF可以使用.ttf格式的字体,也是最简单且使用最方便的字体类,它包含了许多系统自带的字体,不需要额外往项目文件中添加字体文件。但如果你有自定义的字体也可以加到项目中,如果无法使用,可以查看一下ccConfig.h中的CC_FONT_LABEL_SUPPORT是否enable了。
其父类为CCSprite,所以也继承了CCSprite所有的操作,故也可以将其当做CCSprite来用。
-
缺点:CCLabelTTF每次调用 setString(即改变文字)的时候,一个新的OpenGL纹理将会被创建。这意味着setString和创建一个新的标签一样慢。所以,当你需要频繁的更新显示的文字内容的时候,尽可能不去使用该对象,而是使用CCLabelAtlas或者是CCLabelBMFont。
1、常用操作
//
class CC_DLL CCLabelTTF : public CCSprite, public CCLabelProtocol
{
/**
* 创建CCLabelTTF的三种方法
*/
//create(要显示的字符串,字体名称.ttf,字体大小);
//create(要显示的字符串,字体名称.ttf,字体大小,尺寸大小CCSize,水平对其方式)
//create(要显示的字符串,字体名称.ttf,字体大小,尺寸大小CCSize,水平对其方式,垂直对齐方式)
static CCLabelTTF* create(const char *string, const char *fontName, float fontSize);
static CCLabelTTF* create(const char *string, const char *fontName, float fontSize, const CCSize& dimensions, CCTextAlignment hAlignment);
static CCLabelTTF* create(const char *string, const char *fontName, float fontSize, const CCSize& dimensions, CCTextAlignment hAlignment, CCVerticalTextAlignment vAlignment);
/**
* 属性设置
* setString ,
* setHorizontalAlignment , setVerticalAlignment ,
* setDimensions , setFontSize , setFontName
*/
//显示的字符串内容
void setString(const char *label);
const char* getString(void);
//水平对齐方式CCTextAlignment::
//kCCTextAlignmentLeft 左对齐
//kCCTextAlignmentCenter 居中,默认方式
//kCCTextAlignmentRight 右对齐
void setHorizontalAlignment(CCTextAlignment alignment);
CCTextAlignment getHorizontalAlignment();
//垂直对齐方式CCVerticalTextAlignment::
//kCCVerticalTextAlignmentBottom 底部
//kCCVerticalTextAlignmentCenter 中心
//kCCVerticalTextAlignmentTop 顶部,默认方式
void setVerticalAlignment(CCVerticalTextAlignment verticalAlignment);
CCVerticalTextAlignment getVerticalAlignment();
//尺寸大小
void setDimensions(const CCSize &dim);
CCSize getDimensions();
//字体大小
void setFontSize(float fontSize);
float getFontSize();
//字体类型名 如Arial,宋体等
void setFontName(const char *fontName);
const char* getFontName();
/**
* 继承自CCSprite常用函数
* 更多操作见:http://shahdza.blog.51cto.com/2410787/1539567
*/
setColor(ccColor3B); //设置颜色
setPosition(CCPoint); //设置位置
setRotation(float); //旋转角度,角度制0~360
setOpacity(float); //设置透明度
setScale(float); //放缩
setFlipX(float); //左右翻转
}
//
2、代码举例
//
bool HelloWorld::init()
{
if ( !CCLayer::init() )return false;
//获取可视区域尺寸大小
CCSize mysize = CCDirector::sharedDirector()->getVisibleSize();
//获取可视区域的原点位置
CCPoint origin = CCDirector::sharedDirector()->getVisibleOrigin();
//屏幕正中心位置
CCPoint midPos = ccp(mysize.width/2, mysize.height/2);
//创建CCLabelTTF的三种方法
CCLabelTTF* lb1 = CCLabelTTF::create("aaaaaaaa", "arial", 20);
CCLabelTTF* lb2 = CCLabelTTF::create("bbbbbbbb", "宋体", 40, CCSizeMake(50,100), CCTextAlignment::kCCTextAlignmentCenter);
CCLabelTTF* lb3 = CCLabelTTF::create("cccccc", "黑体", 40, CCSizeMake(480,320), CCTextAlignment::kCCTextAlignmentRight, CCVerticalTextAlignment::kCCVerticalTextAlignmentBottom);
//设置位置,屏幕中心
lb1->setPosition( midPos );
lb2->setPosition( midPos );
lb3->setPosition( midPos );
//添加到HelloWorld层中
this->addChild(lb1);
this->addChild(lb2);
this->addChild(lb3);
//其他操作
lb1->setColor( ccc3(255, 0, 0) ); //设置颜色ccc3
lb1->setRotation(60.0f); //旋转
lb2->setColor( cocos2d::ccBLUE ); //设置颜色ccBLUE
lb3->setString("hello world!"); //设置文字内容
}
//
3、运行结果
使用 TTFConfig ,好处是可以重复使用字体的配置信息,不用每次都指定字体名称和尺寸。
TTFConfig ttfConfig("fonts/Consolas.ttf", 24);
auto labelHello = Label::createWithTTF(ttfConfig, "Hello, TTFConfig");
labelHello->setPosition(visibleSize.width / 2, visibleSize.height / 2);
labelHello->setString("Reset String");
addChild(labelHello);
位图字体(Bitmap )
所谓位图字体,就是将所有字符全部都打到一张图片中,这样做简单粗暴,
效率也比较高,因为相当于字体都是预渲染好的。缺点是在字符集比较大时,例如所有汉字,那么字符的图片可能会比较大,内存占用率会比较高。并且不够灵活,因为图片的分辨率固定,在高分屏中,位图字体会出现一些锯齿。
CCLabelBMFont
CCLabelBMFont文字是最快速最自由的字体类。
CCLabelBMFont的父类是CCSpriteBatchNode,特色就是以占用更多内存为代价加快标签的更新,这与其他任何CCSprite类相似。CCLabelBMFont相当于每次改变只改变了图片坐标,而CCLabelTTF要重新渲染。 所以,当你需要频繁的更新它们的时候,尽可能的不用去使用标签对象。 LabelAtlas 或者 LabelBMFont 可以帮助我们实现这种效果。
这个类使用之前,需要添加好字体文件,包括一个图片文件(.png)和一个字体坐标文件(.fnt),这两个文件名称必须一样。可以下载一个fnt编辑工具来自定义字体。
值得注意的是:它的每个字母或符号都是单独的一个CCSprite精灵,可以使用getChildByTag(i)来获取第i个位置上的字符,来对每个字符单独设置属性、动作等。
这个类没办法指定字体的字号,但可以用Scale属性进行缩放来调整大小。
1、常用操作
//
class CC_DLL CCLabelBMFont : public CCSpriteBatchNode, public CCLabelProtocol, public CCRGBAProtocol
{
/**
* 创建CCLabelBMFont方法
*/
//create(要显示的字符串,字体资源名称.fnt)
static CCLabelBMFont * create(const char *str, const char *fntFile);
/**
* 属性设置
* setFntFile , setString ,
* setAnchorPoint , setAlignment , setWidth ,
* setScale , setColor , setOpacity
*/
//设置字体资源名称.fnt
void setFntFile(const char* fntFile);
const char* getFntFile();
//设置内容
virtual void setString(const char *newString);
virtual const char* getString(void);
//设置锚点
virtual void setAnchorPoint(const CCPoint& var);
//水平对齐方式CCTextAlignment::
//kCCTextAlignmentLeft 左对齐
//kCCTextAlignmentCenter 居中
//kCCTextAlignmentRight 右对齐
virtual void setAlignment(CCTextAlignment alignment);
//设置宽度? 可是我用了好像都不知道是什么效果...
virtual void setWidth(float width);
//放缩
virtual void setScale(float scale);
virtual void setScaleX(float scaleX);
virtual void setScaleY(float scaleY);
//设置颜色
virtual void setColor(const ccColor3B& color);
virtual const ccColor3B& getColor(void);
//透明度0~255,其中255为不透明
virtual void setOpacity(GLubyte opacity);
};
//
2、代码举例
//
//创建两个CCLabelBMFont字体
CCLabelBMFont* lb5 = CCLabelBMFont::create("hello", "fonts/bitmapFontTest.fnt");
CCLabelBMFont* lb6 = CCLabelBMFont::create("world", "fonts/bitmapFontTest.fnt");
//设置位置
lb5->setPosition( midPos );
lb6->setPosition( midPos - ccp(0,100) );
//添加到Layer层中
this->addChild(lb5);
this->addChild(lb6);
//属性设置
lb5->setColor(ccRED); //设置字体颜色为红色
lb6->setString("abc"); //设置内容
//获取某个位置的字母,像精灵一样使用
CCSprite* lb5_c1 = (CCSprite*)lb5->getChildByTag(0); //获取第0个字母h
CCSprite* lb5_c2 = (CCSprite*)lb5->getChildByTag(3); //获取第3个字母l
lb5_c1->setColor(ccc3(0,255,0)); //设置为绿色
lb5_c2->setScale(2.0f); //放大
//
3、运行结果
CCLabelAtlas
atlas:词典意思是地图集, 我想它是用来表示多个图片拼在一起的感觉
CCLabelAtlas一般常用来显示数字信息,如分数、排名等。如果你用cocos2d-x项目模板创建过项目,那么你已经看过它的效果了,就是左下角显示帧率的数字。 因为帧率一直在变,使用CCLabelTTF的话效率太低,因为只是数字所以也犯不上使用CCLabelBMFont加载那么大的文字图像,所以使用这个比较合适。而资源一般来自一张.png图片,或.plist文件。不过它也可以用来显示其他字符,如英文字符。
当然CCLabelAtlas继承于CCNode类,故可以使用父类的一些函数,如:放缩、旋转等操作。
特别注意:
- CCLabelAtlas使用的图片资源的每块字符的大小必须是固定的,不然会出错。若要改变字体大小,只能通过放缩来实现。
- 图片资源要按照 连续的ASCII 顺序排列,我们通过设置第一个字符的 ASCII编码,这样,Cocos2d-x就可以根据首位编码和字符的固定大小直接计算出不同字符对应的图形了。
比如说,我们准备显示 0-9 十个数字,我们可以在一张图片中制作好这十个数字。每个数字都有相同的宽度和高度。将它保存在资源中。别忘了设置复制。
CCLabelAtlas* diceCount=CCLabelAtlas::labelWithString("1:", "nums_font.png", 14, 21, '0');
-
第一个参数:显示的内容:1x,你也许会奇怪为什么是1x,因为使用的png图必须是连续的,因为程序内部是以连续的ascall码识别的。实际ascii中9的后一位字符是”:“,而图资源9的后一位被“x”占用,所以要实现x就得用”:“代替。
-
第二个参数:图片的名字
-
第三个参数:每一个数字的宽
-
第四个参数:每一个数字的高
-
每五个数字:开始字符
LabelAtlas* diceCount = CCLabelAtlas::create("100:", "nums_font.png", 14, 21, '0');
diceCount->setPosition(Point(visibleSize.width - 150, visibleSize.height / 2 - 50));
addChild(diceCount);