cocos2d-x学习笔记(19)--label 、label atlas
本文出自http://www.wenbanana.com稻草人博客,欢迎访问!
在正式开讲前,还是要做一些准备工作。
首先讲讲一个ccV3F_C4B_T2F_Quad类的使用,大家不要被这个长长的名称吓到,只需来个刨根问底,就对它的使用方法一目了然了。下面我把,官方文档上的资料整理了一下放在一起:
ccV3F_C4B_T2F_Quad member list: ccV3F_C4B_T2F tl(top left) ccV3F_C4B_T2F bl(bottom left) ccV3F_C4B_T2F tr(top rignt) ccV3F_C4B_T2F br(bottom right) Detailed Description:a Point with a vertex point, a tex coord point and a color 4B (ccV3F_C4B_T2F这个点是有顶点、纹理坐标和颜色设置三个组成) ccV3F_C4B_T2F member list: ccVertex3F vertices ccColor4B colors ccTex2d texCoords Detailed Description:A vertex composed of 2 floats: x, y. (ccVertex3F这个顶点是有x、y坐标组成(注:2D游戏只用到平面坐标,无需z坐标)) ccVertex3F member list: GLfloat x GLfloat y GLfloat z Detailed Description:RGBA color composed of 4 bytes. ccColor4B member list: GLubyte r GLubyte g GLubyte b GLubyte a Detailed Description:A texcoord composed of 2 floats: u, y. ccTex2F member list: GLfloat u GLfloat v
就是说ccV3F_C4B_T2F_Quad这个类有四个成员属性,它们都是ccV3F_C4B_T2F类,分别表示左上,左下,右上,右下;
而ccV3F_C4B_T2F这个类有三个成员属性,它们分别是设置顶点坐标、纹理坐标和颜色;
然后就是对应上面三个类(ccVertex3F、ccColor4B和ccTex2d)的成员属性了;
第二个要补充的是ASICC表,这里我先上传,用处到后面再解释:
接下来就开始进入主题了..................
step1:创建cocos2d-x工程,命名为labelAtlas;
step2:在HelloWorldScene.h中添加四个类:
class BasicLayer:public CCLayer { public: BasicLayer(); ~BasicLayer(); void backMenuCallback(CCObject* pSender); void restartMenuCallback(CCObject* pSender); void nextMenuCallback(CCObject* pSender); }; class TextureAtlasTest:public BasicLayer { protected: CCTextureAtlas* m_atlas; public: TextureAtlasTest(); ~TextureAtlasTest(); virtual void draw(); }; class LabelAtlasTest:public BasicLayer { protected: ccTime m_time; public: LabelAtlasTest(); ~LabelAtlasTest(); void update(ccTime dt); }; class LabelTest:public BasicLayer { protected: ccTime m_time; public: LabelTest(); ~LabelTest(); void update(ccTime dt); };
step3:在HelloWorldScene.cpp中添加下面代码:
先添加一些常量和全局变量
static int index = 1; const int MAX_INDEX = 3; const int tagAtlas = 1;//用于标记CCLabelAtlas对象 const int tagLabel = 2;//用于标记CCLabelTFT对象
CCLayer* runThisTest(int index) { switch(index) { case 1: return new TextureAtlasTest(); case 2: return new LabelAtlasTest(); case 3: return new LabelTest(); } return NULL; }
CCLayer* runThisTest(int index) { switch(index) { case 1: return new TextureAtlasTest(); case 2: return new LabelAtlasTest(); case 3: return new LabelTest(); } return NULL; }
然后添加成员函数:
/************************************************************************/ /*BasicLayer */ /************************************************************************/ BasicLayer::BasicLayer() { CCSize size = CCDirector::sharedDirector()->getWinSize(); CCLabelTTF* backLabel = CCLabelTTF::labelWithString("back", "Arial", 30); CCLabelTTF* restartLabel = CCLabelTTF::labelWithString("restart", "Arial", 30); CCLabelTTF* nextLabel = CCLabelTTF::labelWithString("next", "Arial", 30); CCMenuItemLabel* backItem = CCMenuItemLabel::itemWithLabel(backLabel, this, menu_selector(BasicLayer::backMenuCallback)); CCMenuItemLabel* restartItem = CCMenuItemLabel::itemWithLabel(restartLabel, this, menu_selector(BasicLayer::restartMenuCallback)); CCMenuItemLabel* nextItem = CCMenuItemLabel::itemWithLabel(nextLabel, this, menu_selector(BasicLayer::nextMenuCallback)); CCMenu* backMenu = CCMenu::menuWithItem(backItem); CCMenu* restartMenu = CCMenu::menuWithItem(restartItem); CCMenu* nextMenu = CCMenu::menuWithItem(nextItem); addChild(backMenu,1); addChild(restartMenu,1); addChild(nextMenu,1); backItem->setPosition(ccp(size.width / 2 - 100, 50)); restartItem->setPosition(ccp(size.width / 2 , 50)); nextItem->setPosition(ccp(size.width / 2 + 100, 50)); backMenu->setPosition(CCPointZero); restartMenu->setPosition(CCPointZero); nextMenu->setPosition(CCPointZero); } BasicLayer::~BasicLayer() { } void BasicLayer::backMenuCallback(CCObject* pSender) { if(index == 1) return ; index--; CCScene *scene = new CCScene(); scene->addChild(runThisTest(index)); CCDirector::sharedDirector()->replaceScene(scene); scene->release(); } void BasicLayer::restartMenuCallback(CCObject* pSender) { CCScene *scene = new CCScene(); scene->addChild(runThisTest(index)); CCDirector::sharedDirector()->replaceScene(scene); scene->release(); } void BasicLayer::nextMenuCallback(CCObject* pSender) { if(index == MAX_INDEX) return ; index++; CCScene *scene = new CCScene(); scene->addChild(runThisTest(index)); CCDirector::sharedDirector()->replaceScene(scene); scene->release(); } /************************************************************************/ /*TextureAtlasTest */ /************************************************************************/ TextureAtlasTest::TextureAtlasTest() { m_atlas = CCTextureAtlas::textureAtlasWithFile("atlastest.png",3 ); m_atlas->retain(); CCSize size = CCDirector::sharedDirector()->getWinSize(); //ccV3F_C4B_T2F_Quad quad = { // {{0,0,0},ccc4(255,255,255,255),{0.0f,1.0f},}, // bottom left // {{size.width,0,0},ccc4(255,255,255,0),{1.0f,1.0f},}, // bottom right // {{0,size.height,0},ccc4(255,255,255,0),{0.0f,0.0f},}, // top left // {{size.width,size.height,0},{255,255,255,255},{1.0f,0.0f},}, // top right //}; ccV3F_C4B_T2F_Quad quad = { {{40,40,0},ccc4(255,255,255,255),{0.0f,0.2f},}, // bottom left {{120,80,0},ccc4(255,0,0,255),{0.5f,0.2f},}, // bottom right {{40,160,0},ccc4(255,255,255,255),{0.0f,0.0f},}, // top left {{160,160,0},ccc4(0,255,0,255),{0.5f,0.0f},}, // top right }; m_atlas->updateQuad(&quad,1); } TextureAtlasTest::~TextureAtlasTest() { m_atlas->release(); } void TextureAtlasTest::draw() { m_atlas->drawQuads(); } /************************************************************************/ /*LabelAtlasTest */ /************************************************************************/ LabelAtlasTest::LabelAtlasTest() { CCSize size = CCDirector::sharedDirector()->getWinSize(); m_time = 0; CCLabelAtlas* atlas = CCLabelAtlas::labelWithString("0123456789", "fps_images.png", 16,32,'.'); addChild(atlas, 0, tagAtlas); atlas->setPosition(ccp(size.width / 2, size.height / 2)); schedule(schedule_selector(LabelAtlasTest::update)); } LabelAtlasTest::~LabelAtlasTest() { } void LabelAtlasTest::update(ccTime dt) { m_time += dt; char str[20] = {0}; sprintf(str, "%2.2f", m_time); CCLabelAtlas* label = (CCLabelAtlas*)getChildByTag(tagAtlas); label->setString(str); } /************************************************************************/ /*LabelTest */ /************************************************************************/ LabelTest::LabelTest() { CCSize size = CCDirector::sharedDirector()->getWinSize(); m_time = 0; char str[20] = {0}; sprintf(str, "%2.2f", m_time); CCLabelTTF* label = CCLabelTTF::labelWithString(str, "Arial", 30); addChild(label, 0, tagLabel); label->setPosition(ccp(size.width / 2, size.height / 2)); schedule(schedule_selector(LabelTest::update)); } LabelTest::~LabelTest() { } void LabelTest::update(ccTime dt) { m_time += dt; char str[20] = {0}; sprintf(str, "%2.2f", m_time); CCLabelTTF* label = (CCLabelTTF*)getChildByTag(tagLabel); label->setString(str); }
最后是修改HelloWorld::scene函数,将HelloWorld *layer = HelloWorld::node();改为 LabelTest* layer = new LabelTest();
下面解释下 CCLabelAtlas* atlas = CCLabelAtlas::labelWithString("0123456789", "fps_images.png", 16,32,'.');这个函数。
第一个参数是显示的内容;
第二个参数是图片资源名称;
第三个参数是每个字符的宽度,我使用的字符图片总宽度是265px,使用16px刚好是每个字符的宽度,16 x 16 = 256,这里我把图片中后面空白处算成四个字符,故一共有16字符宽度;
第四个参数是每个字符的高度,这里就是图片的宽度32px;
第五个参数是开始字符,字符图片中第一个字符时 '.';
这里要要说明一点的是,上图中的字符顺序和ASICII表中的字符顺序是一样的,字符之间的ASICII码是相连的。
这里我把两种设置label的方法都列举了,一种是使用CCLabelTFT,一种是使用CCLabelAtlas,两者的使用机制是有差别的。
CCLabelTFT是将要显示的字符串生成一张位图,然后再进行渲染。
而CCLabelAtlas是预先将图片加入到缓存中。
因此,在频繁地调用setString时,CCLabelTFT效率就慢得多。
step4:编译运行程序,效果如下:
源代码下载地址:http://download.csdn.net/download/wen294299195/4539722