Cocos2d-x-03: 字符串 标签和菜单

作者:慧科集团华东校区-朱家聪老师,转载请注明出处及本链接。

字符串 标签和菜单

字符串 String

在Cocos2d-x中,能够使用三种类型的字符串

const char * C语言环境下的字符指针类型,用于表示字符串
std::string C++环境下字符串类型
cocos2d::__String cocos2d-x中的字符串类型

C和C++中的字符串类型转换

前两种类型的字符串在C++中已有使用过,这边简单介绍一下两者的互相转换。

//使用C语言类型的字符串来构造string
string s1 = string("Hello");
const char * cString1 = "world";
string s2 = cString1;

//C++中的string转化为C语言中的字符串
const char *cString2 = s1.c_str();

cocos2d::__String

cocos2d::__String是在cocos2d-x中的字符串类,它的设计模拟了Objective-C中的NSStri类。__String也可以和其他两种字符串类型进行互相转换。

//构建字符串
__String *hello = __String::create("Hello");
int age = 18;
__String *sayAge = __String::createWithFormat("今年%d岁",age);

//和其他类型的字符串的相互转化
//__String -> const char *
const char * cstring1 = hello->getCString();
//const char * -> __String
__String *cocosString1 = __String::createWithFormat("%s", cstring1);
//std::string -> __String
std::string cppString1 = "hello cpp";
__String *cocosString2 = __String::create(cppString1);
//__String -> std::string
std::string cppString2 = cocosString2->getCString();

标签 Label

Label类的基本使用

在一个完整的游戏中,文字类型分为静态文字和动态文字。静态文字是不会随着游戏运行改变的文字,例如游戏Logo中的游戏名称。而动态文字则是随着用户的变化而发生变化的文字,例如用户名,战斗力数值等文字。一般来说静态文字可以有设计师在制作素材图片时直接绘制到图片中去,这样可以减少游戏运行是渲染文字的操作。而动态文字则常用Label来显示。

Label标签类是在Cocos2d-x 3.X版本后推出的一个新的类,用于在游戏中显示字体。有着更快的缓存代理,更快的渲染速度,不同平台相同视觉效果等特点。Label类可以创建系统字体标签,TTF字体标签,位图字体标签。

系统字体是指按照在当前运行平台操作系统中的字体,要使用系统字体标签需要保证所用的字体已经安装在我们的设备中。
TTF字体标签加载的是TTF字体文件显示文字的标签。
位图字体标签会加载两个文件,分别是纹理图集(.png)和字体坐标文件(.fnt)。

//使用系统字体类型创建Label
auto label1 = Label::createWithSystemFont("Hello World System Font", "Arial", 14);
label1->setPosition(origin.x + visibleSize.width / 2, origin.y + visibleSize.height - 20);
this->addChild(label1, 1);
//使用TTF创建Label
auto label2 = Label::createWithTTF("Hello World TTF Font", "fonts/Marker Felt.ttf", 20);
label2->setPosition(origin.x + visibleSize.width / 2, origin.y + visibleSize.height - 50);
this->addChild(label2, 2);
//使用位图字体创建Label 需要fnt文件和png纹理
auto label3 = Label::createWithBMFont("fonts/bitmapFontTest2.fnt", "Hello World BM Font");
label3->setPosition(origin.x + visibleSize.width / 2, origin.y + visibleSize.height - 100);
this->addChild(label3, 3);

//通过TTFConfig来创建TFF字体
TTFConfig ttfConfig("fonts/Marker Felt.ttf",
                    36,
                    GlyphCollection::DYNAMIC);
auto label4 = Label::createWithTTF(ttfConfig, "Hello TTF Config 1");
label4->setPosition(origin.x + visibleSize.width / 2, origin.y + visibleSize.height - 150);
this->addChild(label4, 4);

//设置Label外边框宽度(描边)
ttfConfig.outlineSize = 4;
auto label5 = Label::createWithTTF(ttfConfig, "Hello TTF Config 2");
label5->setPosition(origin.x + visibleSize.width / 2, origin.y + visibleSize.height - 200);
//设置字体阴影的颜色和偏移量
label5->enableShadow(Color4B(255,255,255,128), Size(4,-4));
//设置字体颜色
label5->setColor(Color3B::RED);
this->addChild(label5 , 5);

运行结果:


Simulator Screen Shot 2017年5月2日 下午3.30.46

图片集标签

位图标签是将所有字体纹理储存在一个png文件中,然后在所对应的fnt文件中描述这个位图中每一个字所对应的图片的坐标位置和宽高的值。当系统需要渲染一段文字时,首先从fnt文件中读取出每个字的坐标值,然后到png图片中将这个字的图片抠出来显示在屏幕中。LabelAtlas图片集标签的原理类似于位图标签。在图片集标签中,只有一个储存文字纹理的png图片,所有文字在这个纹理中拥有相同的宽和高,并且有固定的排列顺序。所以不再需要fnt文件来记录每个文字所对应的坐标值了。

font
auto label6 = LabelAtlas::create("ABCDEF",      //显示的文字内容
                                 "fonts/tuffy_bold_italic-charmap.png", //纹理图片
                                 44,            //每个文字的宽度
                                 62,            //每个文字的高度
                                 ' ');          //起始文字
label6->setPosition(origin.x + visibleSize.width / 2, origin.y + visibleSize.height - 210);
label6->setAnchorPoint(Vec2(0.5, 0.5));
this->addChild(label6);
AllFontLabel

菜单 Menu

菜单类Menu,继承于Layer。相关的类有菜单项MenuItem,MenuItem继承于Node。每个MenuItem有三种不同的状态:正常,选中,不可用。在MenuItem下又能派生出多个子类。MenuItemLabel,MenuItemSprite和MenuItemToggle。其中MenuItemLabel类是文本菜单,有两个子类:MenuItemAtlasFont和MenuItemFont。MenuItemSprite是精灵菜单,有一个子类MenuItemImage。MenuItemToggle是开关菜单类。


Cocos2d-x-03: 字符串 标签和菜单_第1张图片

文本菜单

文本菜单项类MenuItemLabel只能用于显示文本,包括MenuItemFont和MenuItemAtlasFont两个子类。其本身是一个抽象类,具体在使用时都是使用它的两个子类来实现具体功能。我们可以通过这两个类来创建我们需要的菜单项,然后添加到菜单中去。最后将菜单对象加入到当前场景中去。

//开始界面的背景图片
Sprite *bg = Sprite::create("background.png");
bg->setPosition(origin.x + visibleSize.width / 2, origin.y + visibleSize.height / 2);
bg->setContentSize(Size(640,480));
this->addChild(bg);
//设置菜单项的样式
MenuItemFont::setFontName("Times New Roman");
MenuItemFont::setFontSize(36);
//创建两个菜单项
MenuItemFont *item1 = MenuItemFont::create("Start Game", CC_CALLBACK_1(HelloWorld::callBackItem1, this));
MenuItemAtlasFont *item2 = MenuItemAtlasFont::create("Help", "fonts/tuffy_bold_italic-charmap.png", 22, 31, ' ', CC_CALLBACK_1(HelloWorld::callBackItem2, this));

//创建菜单对象
Menu *mn = Menu::create(item1,item2,NULL);
//设置水平居中对齐
mn->alignItemsVertically();
this->addChild(mn);

运行结果:


MenuResult

在菜单项的创建过程中,需要给菜单项绑定一个点击的回调(callback)。这里使用了一个宏定义CC_CALLBACK_1,这个宏定义的作用是定义一个回调函数,并且和一个对象绑定在一起。1表示这个函数只有一个输出参数,HelloWorld::callBackItem1是函数指针,this表示函数所在的对象。在使用CC_CALLBACK_1宏定义的时候,需要注意的是,HelloWorld::callBackItem1后面不要加上()。

CC_CALLBACK_1(__selector__, __target__, ...)

在菜单项的回调函数中,需要传入一个 Ref *pSender参数。这个sender指的是回调函数消息的发送者。在这个菜单点击事件中,回调函数消息的发送者就是这个菜单项本身。

void HelloWorld::callBackItem1(Ref *pSender){
    MenuItemFont *item = (MenuItemFont *)pSender;
    
    cout<<"开始游戏"<

精灵菜单和图片菜单

精灵菜单项

精灵菜单项MenuItemSprite,在精灵菜单中包含有多个精灵,并且可以像其他的精灵一样制作各种动画。在创建精灵菜单项之前,首先需要创建三个不同状态下的精灵对象。然后使用这几个精灵对象来构造一个精灵菜单项。

                                   
static MenuItemSprite * create(Node* normalSprite,      //普通状态下的精灵  
                               Node* selectedSprite,    //选中状态下的精灵
                               Node* disabledSprite,    //失效状态下的精灵
                               const ccMenuCallback& callback); //回调函数

图片菜单项

图片菜单项MenuItemImage是精灵菜单项的派生类。主要是使用不同的图片来完成菜单项的创建。

MenuItemImage * MenuItemImage::create(const std::string& normalImage,   //普通状态图片
                                      const std::string& selectedImage, //选中状态图片
                                      const std::string& disabledImage, //失效状态图片
                                      const ccMenuCallback& callback);  //按钮被单击时的回调

创建菜单项

//创建三个精灵对象
Sprite *normal = Sprite::create("start_N.jpg");
Sprite *selected = Sprite::create("start_S.jpg");
Sprite *disabled = Sprite::create("start_D.jpg");

//创建菜单项
MenuItemSprite *item = MenuItemSprite::create(normal, selected, disabled, CC_CALLBACK_1(HelloWorld::callBackItem1, this));
//设置位置
item->setPosition(Vec2(origin.x + visibleSize.width / 2, origin.y + visibleSize.height / 2));
//图片菜单项
MenuItemImage *colseItem= MenuItemImage::create("Power_N.jpg",
                                                "Power_S.jpg",
                                                "Power_D.jpg",
                                                CC_CALLBACK_1(HelloWorld::callColoseNextButton, this));
colseItem->setPosition(Vec2(origin.x + 30,origin.y + 30));

//创建菜单对象
Menu *mn = Menu::create(item,nextItem,NULL);
mn->setPosition(Vec2::ZERO);
this->addChild(mn);

运行结果:


ImageSprite

开关菜单

开关菜单项MenuItemToggle,是一种具有状态切换功能的菜单项。

static MenuItemToggle * createWithCallback(const ccMenuCallback& callback,  //回调函数
                                           MenuItem* item, ...);    //切换的多个菜单项

在之前的案例中,添加一个开关菜单项,使用两个文字类型的MenuItemFont菜单项来创建。

//创建两个状态的菜单项
MenuItemFont *onItem = MenuItemFont::create("开");
MenuItemFont *offItem = MenuItemFont::create("关");


MenuItemToggle *toggle = MenuItemToggle::createWithCallback(CC_CALLBACK_1(HelloWorld::callBackToggle, this), onItem, offItem, NULL);
toggle->setPosition(Vec2(origin.x+visibleSize.width - 30, origin.y+visibleSize.height-30));



//创建菜单对象
Menu *mn = Menu::create(item,nextItem, toggle,NULL);
mn->setPosition(Vec2::ZERO);
this->addChild(mn);

运行效果:


ToggleItem

你可能感兴趣的:(Cocos2d-x-03: 字符串 标签和菜单)