cocos2d-x中字體標簽提供了CCLabelAtlas, CCLabelBMFont CCLabelTTF
1.CCLabelAtlas速度快,支持簡單有限的幾個字符或數字集合
2.CCLabelBMFont
我們可以用CCLabelBMFont來加載字體編輯器生成的.plist文件,但是當顯示的文字很多時,這種做法就有點費時費力了
如:我們想顯示游戲中劇情介紹
3.CCLabelTTF
支持選擇一種字體來顯示文字,但是只支持系統中默認字體
CCLabelTTF* pLabel = CCLabelTTF::create("Hello World", "Arial", 24);
問題:我們在Android游戲中想顯示游戲劇情,想用自己指定的一種字體gril.ttf(非系統默認字體),怎么辦
其實cocos2d-x已經提供了幫我們實現了
構造CCLabelTTF中指定的字體名傳給了CCTexture2D
void CCLabelTTF::updateTexture()
{
CCTexture2D *tex;
if (m_tDimensions.width == 0 || m_tDimensions.height == 0)
{
tex = new CCTexture2D();
tex->initWithString(m_string.c_str(), m_pFontName->c_str(), m_fFontSize * CC_CONTENT_SCALE_FACTOR()) ;
}
else
{
tex = new CCTexture2D();
tex->initWithString(m_string.c_str(),
CC_SIZE_POINTS_TO_PIXELS(m_tDimensions),
m_hAlignment,
m_vAlignment,
m_pFontName->c_str(),
m_fFontSize * CC_CONTENT_SCALE_FACTOR());
}
.
}
CCTexture2D又將字體名傳給了CCImage{
CCTexture2D *tex;
if (m_tDimensions.width == 0 || m_tDimensions.height == 0)
{
tex = new CCTexture2D();
tex->initWithString(m_string.c_str(), m_pFontName->c_str(), m_fFontSize * CC_CONTENT_SCALE_FACTOR()) ;
}
else
{
tex = new CCTexture2D();
tex->initWithString(m_string.c_str(),
CC_SIZE_POINTS_TO_PIXELS(m_tDimensions),
m_hAlignment,
m_vAlignment,
m_pFontName->c_str(),
m_fFontSize * CC_CONTENT_SCALE_FACTOR());
}

}
(PS:這里調用的是android平臺下的CCImage類(./platform/android/CCImage.h)
而不是win32平臺下的CCImage類(./platform/win32/CCImage.h) )
android平臺下的CCImage
bool CCImage::initWithString(
const char * pText,
int nWidth/* = 0*/,
int nHeight/* = 0*/,
ETextAlign eAlignMask/* = kAlignCenter*/,
const char * pFontName/* = nil*/,
int nSize/* = 0*/)
{
bool bRet = false;
do
{
CC_BREAK_IF(! pText);
BitmapDC &dc = sharedBitmapDC();
CC_BREAK_IF(! dc.getBitmapFromJava(pText, nWidth, nHeight, eAlignMask, pFontName, nSize));
// assign the dc.m_pData to m_pData in order to save time
m_pData = dc.m_pData;
CC_BREAK_IF(! m_pData);
m_nWidth = (short)dc.m_nWidth;
m_nHeight = (short)dc.m_nHeight;
m_bHasAlpha = true;
m_bPreMulti = true;
m_nBitsPerComponent = 8;
bRet = true;
} while (0);
return bRet;
}
const char * pText,
int nWidth/* = 0*/,
int nHeight/* = 0*/,
ETextAlign eAlignMask/* = kAlignCenter*/,
const char * pFontName/* = nil*/,
int nSize/* = 0*/)
{
bool bRet = false;
do
{
CC_BREAK_IF(! pText);
BitmapDC &dc = sharedBitmapDC();
CC_BREAK_IF(! dc.getBitmapFromJava(pText, nWidth, nHeight, eAlignMask, pFontName, nSize));
// assign the dc.m_pData to m_pData in order to save time
m_pData = dc.m_pData;
CC_BREAK_IF(! m_pData);
m_nWidth = (short)dc.m_nWidth;
m_nHeight = (short)dc.m_nHeight;
m_bHasAlpha = true;
m_bPreMulti = true;
m_nBitsPerComponent = 8;
bRet = true;
} while (0);
return bRet;
}
然后調用了android平臺下的BitmapDC
bool getBitmapFromJava(const char *text, int nWidth, int nHeight, CCImage::ETextAlign eAlignMask, const char * pFontName, float fontSize)
{
JniMethodInfo methodInfo;
if (! JniHelper::getStaticMethodInfo(methodInfo, "org/cocos2dx/lib/Cocos2dxBitmap", "createTextBitmap",
"(Ljava/lang/String;Ljava/lang/String;IIII)V"))
{
CCLOG("%s %d: error to get methodInfo", __FILE__, __LINE__);
return false;
}


}
{
JniMethodInfo methodInfo;
if (! JniHelper::getStaticMethodInfo(methodInfo, "org/cocos2dx/lib/Cocos2dxBitmap", "createTextBitmap",
"(Ljava/lang/String;Ljava/lang/String;IIII)V"))
{
CCLOG("%s %d: error to get methodInfo", __FILE__, __LINE__);
return false;
}


}
這里顯示了調用JAVA代碼Cocos2dxBitmap.java下的createTextBitmap函數
/*
* @width: the width to draw, it can be 0
* @height: the height to draw, it can be 0
*/
public static void createTextBitmap(String content, String fontName,
int fontSize, int alignment, int width, int height){
content = refactorString(content);
Paint paint = newPaint(fontName, fontSize, alignment);
TextProperty textProperty = computeTextProperty(content, paint, width, height);
int bitmapTotalHeight = (height == 0 ? textProperty.totalHeight:height);
// Draw text to bitmap
Bitmap bitmap = Bitmap.createBitmap(textProperty.maxWidth,
bitmapTotalHeight, Bitmap.Config.ARGB_8888);
Canvas canvas = new Canvas(bitmap);
// Draw string
FontMetricsInt fm = paint.getFontMetricsInt();
int x = 0;
int y = computeY(fm, height, textProperty.totalHeight, alignment);
String[] lines = textProperty.lines;
for (String line : lines){
x = computeX(paint, line, textProperty.maxWidth, alignment);
canvas.drawText(line, x, y, paint);
y += textProperty.heightPerLine;
}
initNativeObject(bitmap);
}
* @width: the width to draw, it can be 0
* @height: the height to draw, it can be 0
*/
public static void createTextBitmap(String content, String fontName,
int fontSize, int alignment, int width, int height){
content = refactorString(content);
Paint paint = newPaint(fontName, fontSize, alignment);
TextProperty textProperty = computeTextProperty(content, paint, width, height);
int bitmapTotalHeight = (height == 0 ? textProperty.totalHeight:height);
// Draw text to bitmap
Bitmap bitmap = Bitmap.createBitmap(textProperty.maxWidth,
bitmapTotalHeight, Bitmap.Config.ARGB_8888);
Canvas canvas = new Canvas(bitmap);
// Draw string
FontMetricsInt fm = paint.getFontMetricsInt();
int x = 0;
int y = computeY(fm, height, textProperty.totalHeight, alignment);
String[] lines = textProperty.lines;
for (String line : lines){
x = computeX(paint, line, textProperty.maxWidth, alignment);
canvas.drawText(line, x, y, paint);
y += textProperty.heightPerLine;
}
initNativeObject(bitmap);
}
在newPaint函數中調用了字體加載
private static Paint newPaint(String fontName, int fontSize, int alignment){
Paint paint = new Paint();
paint.setColor(Color.WHITE);
paint.setTextSize(fontSize);
paint.setAntiAlias(true);
/*
* Set type face for paint, now it support .ttf file.
*/
if (fontName.endsWith(".ttf")){ //字體需要.ttf結束
try {
//Typeface typeFace = Typeface.createFromAsset(context.getAssets(), fontName);
Typeface typeFace = Cocos2dxTypefaces.get(context, fontName);
paint.setTypeface(typeFace);
} catch (Exception e){
Log.e("Cocos2dxBitmap",
"error to create ttf type face: " + fontName);
/*
* The file may not find, use system font
*/
paint.setTypeface(Typeface.create(fontName, Typeface.NORMAL));
}
}
else {
paint.setTypeface(Typeface.create(fontName, Typeface.NORMAL));
}
.......
return paint;
}
Paint paint = new Paint();
paint.setColor(Color.WHITE);
paint.setTextSize(fontSize);
paint.setAntiAlias(true);
/*
* Set type face for paint, now it support .ttf file.
*/
if (fontName.endsWith(".ttf")){ //字體需要.ttf結束
try {
//Typeface typeFace = Typeface.createFromAsset(context.getAssets(), fontName);
Typeface typeFace = Cocos2dxTypefaces.get(context, fontName);
paint.setTypeface(typeFace);
} catch (Exception e){
Log.e("Cocos2dxBitmap",
"error to create ttf type face: " + fontName);
/*
* The file may not find, use system font
*/
paint.setTypeface(Typeface.create(fontName, Typeface.NORMAL));
}
}
else {
paint.setTypeface(Typeface.create(fontName, Typeface.NORMAL));
}
.......
return paint;
}
(PS:Typeface類定義字體和字體內在的類型。這個類被用在畫筆Paint設置的時候,比如用textSize,textSkewX和textScale設置來指定text在畫的時候如何來顯示和測量。
android中用Typeface來指定字體)另一點需要注意的是:字體需要.ttf結束
使用方法:
1.在proj.android\assets文件夾中添加girl.ttf
2.程序中調用對應的字體就可以了
CCSize size = CCDirector::sharedDirector()->getWinSize();
CCLabelTTF* label = CCLabelTTF::create("少女HelloWorld", "girl.ttf", 24);
label->setPosition(ccp(size.width/2, size.height/2));
addChild(label);
3.如果你需要顯示漢字,則需要將包含有字符串的文件(如.cpp)轉換為UTF-8格式編碼,否則會顯示亂碼CCLabelTTF* label = CCLabelTTF::create("少女HelloWorld", "girl.ttf", 24);
label->setPosition(ccp(size.width/2, size.height/2));
addChild(label);
IOS和win32平臺沒有測試,相信的差不多
附上測試圖片:

哈哈 可以在游戲中打包自己想要的字體啦