Cocos2d-x provides a easy to use UI
api that takes care of your GUI needs.
Some of these include Label
, Menu
, MenuItems
and ......
XXX: screenshot of each widget
XXX: Just don't metion the "Atlas" font. It is deprecated.
Cocos2d-x provides a Label
object that can create TTF, Atlas, BMFont and
SystemFont labels.
BMFont
is a label type that uses a bitmap font. Bitmap fonts consist of a
matrix of dots or pixels representing the image of each glyph in each face and
size. It is very fast and easy to use, but not scalable, requiring a separate
font for each size.
As the Label
class is subclass of SpriteBatchNode
each character is a Sprite
and can be rotated, scaled, tinted, changes in anchor point and most any other
property change derived from a Node
object.
Creating a BMFont
label requires two files: a .fnt file and an image
representation of each character in .png format. If you are using a tool like
Glyph Designer these files are created automatically for you. Creating a
BMFont
label:
auto myLabel = Label::createWithBMFont("myFont.fnt", "My Label Text");
All of the characters in the string parameter should be found in the provided
"MyBar.fnt" file, otherwise it won't be rendered. If you render a Label
and
it is missing characters, make sure they exist in your "MyBar.fnt" file.
TTF
is a label type that uses a True Type Font. To create one you need to
specify a .ttf
font file name, text string and a size. Unlike BMFont
, TTF
can render size changes without the need for a separate font files. Creating a
TTF
label:
auto myLabel = Label::createWithTTF("myFont.ttf", "My Label Text", 16);
Although it is more flexible than BMFont
, TTF
is slower and changing
properties like the font face and size is an expensive operation.
If you need several TTF
labels that all have the same properties you can create
a TTFConfig
object to manage them. A TTFConfig
allows you to set the properties
that all of your TTF
labels would have in common. You can create one like:
// 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");
A TTFConfig
can also be used for displaying Chinese, Japanese and Korean characters.
SystemFont
is a label type that uses the default system font and font size.
This is a font that is meant not to have its properties changed. You should think
of it as system font, system rules. Creating a SystemFont
label:
auto myLabel = Label::createWithSystemFont("My Label Text", "Arial", 16);
Atlas
is a label type that uses an atlas image file. When rendering an Atlas
label, all characters must be contained in the atlas image file or else it will
not be rendered. Each character in the label is its own Sprite
object. Creating
an Atlas
label:
auto myLabel = Label::createWithCharMap("fonts/labelatlas.png", 24, 32, '0');
The 2rd and 3rd parameters of Label::createWithCharMap
is the width and height
of each character in the texture atlas file. This is new, BMFont
has a fixed
width and height and TTF
the width and height is uniform. You can consider an
Atlas
label as a simple version of BMFont
with limited font customization.
It runs as fast as BMFont
.
###Label Effects
Label
objects can have effects applied to them. Not all label types support
all effects. Some effects include shadow, outline, and glow.
// shadow effect is supported by all Label types
myLabel->enableShadow();
// outline effect is TTF only, specify the outline color desired
label->enableOutline(Color4B(100, 50, 100, 100));
// glow effect is TTF only, specify the glow color desired.
label->enableGlow(Color4B(100, 50, 100, 100));
A Menu
is a way to navigate through game options. Menus often contain options
like Play, Quit, Settings and About. This is usually in the form of
buttons that are pressed.
A Menu
is a special Node
object. To create an empty Menu
:
auto myMenu = Menu::create();
MenuItems
are the core of any Menu
. Menu Items usually have a normal
and
a selected
state as well as a callback...something that happens when the
MenuItem
is selected.
// creating a menu with a single item
// create a menu item
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",
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);
A lambda function is a function that you can write inline in your source code.
Cocos2d-x makes use of lambdas. You can even use them as callbacks! Besides
Menu
callbacks lambdas can be used for a variety of functions.
A simple lambda:
auto func = [] () { cout << "Hello world"; };
func(); // now call the function
Using a lambda as an Action
:
auto action1 = CallFunc::create([&](){
std::cout << "using a Lambda callback" << std::endl;
});
Creating an std::function using a lambda:
std::function<void()> myFunction = []()
{
std::cout << "From myFunction()" << std::endl;
};
auto action2 = CallFunc::create(myFunction);
Using a lambda as a MenuItem
callback:
auto closeItem = MenuItemImage::create("CloseNormal.png", "CloseSelected.png",
[&](Ref* sender){
// your code here
});
The new GUI module is a widget-based GUI framework, it was original designed for
use with CocosStudio. The root class of the new GUI module is ui::Widget
which
is inherited from ProtectedNode
. A ProtectedNode is designed for holding inner
Node
list such that when you are adding or removing child node from the
ProtectedNode
, the "Innder Node List" won't be touched which is safe to keep
widget's inner rendering components. We can break the GUI down into two distinct
pieces: Widget and Containers.
The Layout
class is the root class of all containers. It inherits from Widget
.
The Layout
class exists mainly for arranging children widgets and clipping.
The LayoutManager
, LayoutParameter
and Margin
classes are used for layout
elements. HBox
, VBox
and RelativeBox
are handy classes for layout children
widgets horizontally, vertically and relatively.
The ScrolView
, ListView
and PageView
are specific containers for certain
usage scenario. We will talk it in another section.
Widgets
are GUI objets that help make creating a user interface easier. Let's
talk about the common widgets that you might use:
A button intercepts a touch event and calls a predefined callback when tapped.
It is inherited from ui::Widget
. This class provide methods for setting the
title, image and other properties of button. A Button
has a normal and
selected state. The appearance of the Button
can change based upon this
state. Creating a Button
is simple:
auto button = Button::create("animationbuttonnormal.png",
"animationbuttonpressed.png");
button->setTitleText("Text Button");
button->setPosition(Vec2(0,0));
button->addTouchEventListener(CC_CALLBACK_2(UIButtonTest::touchEvent, this));
this->addChild(button);
A CheckBox
permits the user to make a binary choice. A Checkbox
can have a
state of normal, selected and disabled. Creating a CheckBox
is simple:
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->setPosition(Vec2(0,0));
checkBox->addEventListener(CC_CALLBACK_2(UICheckBoxTest::selectedEvent, this));
this->addChild(checkBox);
A LoadingBar
could be used to show the progression of an operation, such as
loading, file transfer, etc. It could also be refered to as a status bar.
Creating a LoadingBar
:
auto loadingBar = LoadingBar::create("sliderProgress.png");
loadingBar->setDirection(LoadingBar::Direction::RIGHT);
loadingBar->setPosition(Vec2(0,0));
this->addChild(loadingBar);
A Slider
allows user to set value by moving a indicator. To create a Slider
:
auto slider = Slider::create();
slider->loadBarTexture("sliderTrack.png");
slider->loadSlidBallTextures("sliderThumb.png", "sliderThumb.png", "");
slider->loadProgressBarTexture("sliderProgress.png");
slider->setPosition(Vec2(0,0));
slider->addEventListener(CC_CALLBACK_2(UISliderTest::sliderEvent, this));
this->addChild(slider);
A ImageView
is a placeholder for displaying images. It supports touch events,
focus, percent positioning and percent content size. To create an ImageView
:
auto imageView = ImageView::create("ccicon.png");
imageView->setPosition(Vec2(0,0));
this->addChild(imageView);
It is also possible to create an ImageView
from a SpriteFrame
:
auto imageView = ImageView::create("ccicon.png", TextureResType::PLIST);
imageView->setPosition(Vec2(0,0));
this->addChild(imageView);
A Text
widget is used for display text. It can also use it as a text-only
button. Text
supports system font and TTF fonts. To create a Text
widget:
auto text = Text::create("Text","fonts/MyTTF.ttf",30);
text->setPosition(Vec2(0,0));
this->addChild(text);
You can add effects like shadow, glow and outline just like any Label
object.
A TextBMFont
widget is used for displaying BMFont
text. It supports touch
event, focus, percent positioning and percent content size. Creating a TextBMFont
is list like the Text
widget:
auto textBMFont = TextBMFont::create("BMFont", "bitmapFontTest2.fnt");
textBMFont->setPosition(Vec2(0,0));
this->addChild(textBMFont);
A TextAtlas
widget is used for displaying text as an atlas font. It supports
touch event, focus, percent positioning and percent content size.\
auto textAtlas = TextAtlas::create("1234567890", "labelatlas.png", 17, 22, "0");
textAtlas->setPosition(Vec2(0,0));
this->addChild(textAtlas);
A RichText
widget is used for displaying text, image and custom nodes. It
supports touch event, focus, percent positioning and percent content size. When
receiving a touch event the whole RichText
widget receives the event. To create
a RichText
widget:
auto richText = RichText::create();
richText->ignoreContentAdaptWithSize(false);
richText->setContentSize(Size(100, 100));
auto re1 = RichElementText::create(1, Color3B::WHITE, 255, str1, "Marker Felt", 10);
richText->pushBackElement(re1);
richText->setPosition(Vec2(0,0));
richText->setLocalZOrder(10);
this->addChild(_richText);
A TextField
Widget is used for inputting text. It supports touch event, focus,
percent positioning and percent content size. To create a TextField
widget:
auto textField = TextField::create("input words here","Arial",30);
textField->setPosition(Vec2(0,0));
textField->addEventListener(CC_CALLBACK_2(UITextFieldTest::textFieldEvent, this));
this->addChild(textField);
***Ricardo, I removed ScrollView and ListView for now as the coe was very long and
seems very complicated. If we need to include it I should try and create a smaller,
more concise code example. I alro removed HBox
and VBox
layout as they were only
described for container purposes, as Owen put it.