在正式开讲前,还是要做一些准备工作。

首先讲讲一个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

 

打赏

发表评论

电子邮件地址不会被公开。