您的位置:首页 > 移动开发 > Cocos引擎

cocos2d-x Programmers Guide v3.3 译本和阅读笔记(第6章UI)

2015-12-20 00:35 525 查看

Cocos2d-x Programmers Guide v3.3 译本和阅读笔记

原著是英文,本文只是一个个人的简单理解的中文的非正式翻译,供自己学习使用,参考需谨慎。

向原著的作者SlackMoehrle, Ricardo, Justin, Nite , Kai, Minggo, Wenhai, Tony, Yingtao, Rao 致敬。

第6章:UI

看一看你平时见过的应用,我打赌即使你不知道UI控件是什么也一定能找到。它们不仅仅是游戏专有的,每一个应用都使用UI控件。UI代表什么?UI控件是干什么的?很多问题!

我的控件

UI是一个缩写,代表user interface。就是那些屏幕上的东西。这些包含的项目比如:标签,按钮,菜单,滑动条和视图。Cocos2d-x提供了一系列ui控件使你能够更加方便的为你的项目添加这些控制。这听上去平常,但是即使是一个简单的标签的核心类也会大费周章,何况其他的呢。你能想想写一套自己的自定义控件是多复杂么?不要担心,这已经替你做好了。

标签

Cocos2d-x提供了标签对象。标签可以用真标签类型,位图标签或者系统字体来创建。这个类可以满足所有的需求。

Label BMFont BMFont 是一种使用位图字体的标签。位图中的字体由点阵方式组成。他使用起来非常快速简单,但是由于它需要将字体分割,所以并不能更具不同大小的字体来放缩。每个字实际上都是一个精灵,这就意味着没一个字都能够旋转和放缩,改变色调或者拥有不同的锚点或者其它的任何属性。

创建一个BMFont字体需要两文件: 一个 .fnt文件和 一个png含有所有字体图片的png文件。如果你使用一个像Glyph Designer这样的工具,那么这些文件将会由工具自动生成。创建一个位图字体标签的代码如下:

auto myLabel = Label::createWithBMFont("bitmapRed.fnt", "Your Text");




字符串中的所有文字的信息必须包含在.fnt中,否则将不会被渲染到屏幕上。如果你在屏幕上创建了一个标签对象,而且其中有些字符丢失了,那么就检查一下这些字符的信息在.fnt中是否存在。

Label TTF TTF(True Type Fonts) 与位图字体不同。使用真是字体来渲染,这使得我们不需要为不同大小和颜色的字体创建不同字体文件。使用TTF字体创建标签非常容易。创建一个标签只需要指定一个 .ttf文件明,文字字符串和大小即可。与BMFont不同,TTF字体可以改变大小,而不需要多个字体文件。代码如下:

auto myLabel = Label::createWithTTF("Your Text", "Marker Felt.ttf", 24);




尽管这种字体比位图字体更加灵活,但是ttf字体的渲染的会更慢一些,而且改变属性,比如字体和大小都会带来而外的操作。

如果你需要的是几个不同的ttf标签,但是他们的属性都是一样的,你可以考虑使用TTFConfig对象来管理。一个TTFConfig对象可以让你,一次设置所有标签的属性。你可以把它看成是一个清单,可以让所有的标签具有相同的属性。

你可以这样创建一个TTFConfig:

// create a TTFConfig files for labels to share
TTFConfig labelConfig;
labelConfig.fontFilePath = "myFont.ttf";
labelConfig.fontSize = 16;
labelConfig.glyphs = GlyphCollection::DYNAMIC;
labelConfig.outlineSize = 0;
labelConfig.customGlyphs = nullptr;
labelConfig.distanceFieldEnabled = false;
// create a TTF Label from the TTFConfig file.
auto myLabel = Label::createWithTTF(labelConfig, "My Label Text");




TTFConfig也可用于显示汉语、日语和韩语。

Label SystemFont SystemFont 标签使用系统默认的字体和字号。这就表示没有过多的属性变化。我们应当这样理解它:“系统字体,跟随系统”。创建一个SystemFont标签如下:

auto myLabel = Label::createWithSystemFont("My Label Text", "Arial", 16);




标签的特效

当我们的标签显示在屏幕上,也许我们可以使他们看上去更加美观。获取它们现在看上去太普通太平淡了。好在你不需要创建你自己的字体!标签(Label)对象也提供了一些特效。当然并不是所有的标签都支持所有的特效。这些特效包括阴影,轮廓线和发光。你可以轻易的在一个标签上添加一种或者多种特效:

auto myLabel = Label::createWithTTF("myFont.ttf", "My Label Text", 16);
// shadow effect is supported by all Label types
myLabel->enableShadow();




轮廓线特效:

auto myLabel = Label::createWithTTF("myFont.ttf", "My Label Text", 16);
// outline effect is TTF only, specify the outline color desired
myLabel->enableOutline(Color4B::WHITE, 1));




发光特效

auto myLabel = Label::createWithTTF("myFont.ttf", "My Label Text", 16);
// glow effect is TTF only, specify the glow color desired.
myLabel->enableGlow(Color4B::YELLOW);




菜单和菜单选项

我们对菜单都十分熟悉。我们每天都能在应用中见到菜单。在你的游戏中你可能会使用菜单作为你游戏操作的导航。菜单通常包含一些按钮,比如开始,退出,设置和关于。菜单对象是一个特殊的节点对象。你可以创建一个空的菜单,作为菜单选项的容器。

auto myMenu = Menu::create();


正如之前说道的开始,退出,设置和关于,这些就是你的菜单选项,一个没有选项的菜单是没有意义的。Cocos2d-x提供了创建菜单选项的方式,比如使用标签或者图片。选项通常有两种状态,正常状态和选中状态。当你触碰或者点击选项的时侯就会出发一个回调。你可吧这个看成是一个链式反应。当你点击选项的时候就运行你指定的代码。菜单可以只有一个选项,也可以有多个选项。

// creating a menu with a single item
// create a menu item by specifying images
auto closeItem = MenuItemImage::create("CloseNormal.png", "CloseSelected.png",
CC_CALLBACK_1(HelloWorld::menuCloseCallback, this));
auto menu = Menu::create(closeItem, NULL);
this->addChild(menu, 1);
A menu can also be created by using a Vector of MenuItem objects:
// creating a Menu from a Vector of items
Vector<MenuItem*> MenuItems;
auto closeItem = MenuItemImage::create("CloseNormal.png", "CloseSelected.png"
cf52
,
CC_CALLBACK_1(HelloWorld::menuCloseCallback, this));
MenuItems.pushBack(closeItem);
/* repeat for as many menu items as needed */
auto menu = Menu::createWithArray(MenuItems);
this->addChild(menu, 1);


如果你运行了本章刚才的示例代码,就会先如小文字标签菜单:



Lambda 表达式作为菜单回调

到此,我们已知当点击选项的时对应的回调就会触发。C++11提供了lambda表达式,而且Cocos2d-x完美支持!lambda表达式就是你写在源码中的一个函数。lambdas表达式将在运行时捕获数值并计算,而不是编译时。

一个简单的lambda表达式的例子:

// create a simple Hello World lambda
auto func = [] () { cout << "Hello World"; };
// now call it someplace in code
func();
Using a lambda as a MenuItem callback:
auto closeItem = MenuItemImage::create("CloseNormal.png", "CloseSelected.png",
[&](Ref* sender){
// your code here
});


按钮

我觉得我们可能需要对按钮进行很多的讲解。我们都知道,当我们点击按钮的时候就会触发游戏中的某些事情。也许使用按钮改变场景或者添加精灵。当点击按钮的时候,按钮会接受一个触摸事件并且调用预先定义的回调。按钮有平常态和选中态。它的样子也会随着它的状态而发生变化。创建一个按钮并且定义回调是非常简单的:

#include "ui/CocosGUI.h"
auto button = Button::create("normal_image.png", "selected_image.png", "disabled_image.png")
button->setTitleText("Button Text");
button->addTouchEventListener([&](Ref* sender, Widget::TouchEventType type){
switch (type)
{
case ui::Widget::TouchEventType::BEGAN:
break;
case ui::Widget::TouchEventType::ENDED:
std::cout << "Button 1 clicked" << std::endl;
break;
default:
break;
}
});
this->addChild(button);


如你所见,上面这个例子,我们为按钮的每一个状态指定了一个png图片。这个按钮由下面三个图片组成:



在屏幕上按钮看上去是这个样子:



选项框

我们在纸质表单上都填写过选项框,比如工作申请表、租赁合同等。你的游戏中也会使用选项框。有时候你需要给予你的玩家是或否的选择。这听上去想二进制的0或者1。选项框可以实现这样的过程。一个选项框有平常态、选中态和不可选态。创建一个选项框也很简单:

#include "ui/CocosGUI.h"
auto checkbox = CheckBox::create("check_box_normal.png",
"check_box_normal_press.png",
"check_box_active.png",
"check_box_normal_disable.png",
"check_box_active_disable.png");
checkbox->addTouchEventListener([&](Ref* sender, Widget::TouchEventType type){
switch (type)
{
case ui::Widget::TouchEventType::BEGAN:
break;
case ui::Widget::TouchEventType::ENDED:
std::cout << "checkbox 1 clicked" << std::endl;
break;
default:
break;
}
});
this->addChild(checkbox);


如你所见,上面这个例子,我们为选项狂的每个状态都指定了图片。选项框由5张图片组成:



屏幕上看上去应当如下:



进度条

你玩过这样的游戏么,当内容加载的时候,你不得不等待?这时你很可能看到的是一个进度条,当加载完成的时候进度条就填满了。通常叫做进度条

状态条或者加载条。创建一个进度条:

#include "ui/CocosGUI.h"
auto loadingBar = LoadingBar::create("LoadingBarFile.png");
// set the direction of the loading bars progress
loadingBar->setDirection(LoadingBar::Direction::RIGHT);
this->addChild(loadingBar);


上面这个例子创建了一个进度条,并指定了它的填充方向。这里是向右。但是我们还需要能够改变它的百分比。这也很容易:

#include "ui/CocosGUI.h"
auto loadingBar = LoadingBar::create("LoadingBarFile.png");
loadingBar->setDirection(LoadingBar::Direction::RIGHT);
// something happened, change the percentage of the loading bar
loadingBar->setPercent(25);
// more things happened, change the percentage again.
loadingBar->setPercent(35);
this->addChild(loadingBar);


如你所见,我们指定了一个png图片给进度条。



屏幕上显示如下:



滚动条

有时候需要改变微调一些变量,滚动条非常有用。比如如果你希望你的玩家能够调节角色攻击敌人的力量大小。滚动条允许你的用户通过指示器来设定数值。创建代码如下:

#include "ui/CocosGUI.h"
auto slider = Slider::create();
slider->loadBarTexture("Slider_Back.png"); // what the slider looks like
slider->loadSlidBallTextures("SliderNode_Normal.png", "SliderNode_Press.png", "SliderNode_Disable.png");
slider->loadProgressBarTexture("Slider_PressBar.png");
slider->addTouchEventListener([&](Ref* sender,
Widget::TouchEventType type){
switch (type)
{
case ui::Widget::TouchEventType::BEGAN:
break;
case ui::Widget::TouchEventType::ENDED:
std::cout << "slider moved" << std::endl;
break;
default:
break;
}
});
this->addChild(slider);


如你所见,我们为滚动条的没一个状态都指定了图片。一个滚动条由5个图片组成:



屏幕上显示如下:



文本框

如果你想要你的玩家能够输入游戏主角的名称会怎样?他们要在哪里输入呢?是的,当然是文本框。文本框是一个用来输入文本的控件。它支持触摸事件,焦点,百分比位置和百分比内容尺寸。创建一个文本框代码如下:

#include "ui/CocosGUI.h"
auto textField = TextField::create("","Arial",30);
textField->addTouchEventListener([&](Ref* sender, Widget::TouchEventType type){
std::cout << "editing a TextField" << std::endl;
});
this->addChild(textField);


这个例子创建了一个文本框并指定了回调。

文本框有很多功能可以实现你所有的输入需求。你希望玩家输入密码么?你希望限制玩家输入字符的长度么?文本框不仅实现了这些,还实现了许多其他功能!我们看一个例子:

#include "ui/CocosGUI.h"
auto textField = TextField::create("","Arial",30);
// make this TextField password enabled
textField->setPasswordEnabled(true);
// set the maximum number of characters the user can enter for this TextField
textField->setMaxLength(10);
textField->addTouchEventListener([&](Ref* sender, Widget::TouchEventType type){
std::cout << "editing a TextField" << std::endl;
});
this->addChild(textField);


屏幕显示如下:



当你开始编辑文本框的时候,屏幕上的键盘就会弹出:

内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  cocos2d-x 应用 ui