Cocos2d-xUI组件详解

标签(Label)

  Cocos2d-x提供Label对象给用户,可以使用位图字体,TrueType字体,系统字体创建标签。这个单一的类能处理你所有的标签需求。下面介绍使用各种字体,创建标签的方法。

BMFont

  BMFont是一个使用位图字体创建的标签类型,位图字体中的字符由点阵组成。使用这种字体标签性能非常好,但是不适合缩放。由于点阵的原因,缩放会导致失真。标签中的每一个字符都是一个单独的Sprite,也就是说精灵的属性(旋转,缩放,着色等)控制都适用于这里的每个字符。

  创建BMFont标签需要两个文件,.fnt文件和.png文件。可以使用像Glyph Designer这样的工具来创建位图字体,这些文件将会自动生成。

  使用位图字体创建标签:

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

  所有在标签中出现的字符都应该能在提供的.fnt文件找到,如果找不到,字符就不会被渲染。如果你渲染了一个Label,同时它有丢失字符,记得去查看一下,.fnt文件是否完备。

TTF

  True Type字体和我们上面了解的位图字体不同,使用这种字体很方便,你不需要为每种尺寸和颜色单独使用字体文件。不像BMFont,如果想不失真的缩放,就要提供多种字体文件。

  要创建这种标签,需要制定.ttf字体文件名,文本字符串和字体大小。

  使用TrueType字体创建标签:

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

  虽然使用TruType字体比使用位图字体更灵活、但是它渲染速度较慢,并且更改标签的属性(字体,大小)是一项非常消耗性能的操作。

  如果需要具有相同属性的多个Label对象,那可以创建一个TTFConfig对象来统一配置,TTFConfig对象允许设置所有标签的共同属性。

  通过以下方式创建一个TTConfig对象:

//为所有的Label标签创建一个TTFConfig共享文件配置
TTFConfig labelConfig;
labelConfig.fontFilePath = "myFont.ttf";
labelConfig.fontSize = 16;
labelConfig.glyphs = GlyphCollection::DYNAMIC;
labelConfig.outlineSize = 0;
labelConfig.customGlyphs = nullptr;
labelConfig.distanceFieldEnabled = false;//从TTFConfig文件中创建TTF Label标签
auto myLabel = Label::createWithTTF(labelConfig,"My Label Text");

  TTFConfig也能用于展示中文,日文,韩文的字符。

SystemFont

  SystemFont是一个使用系统默认字体,默认字体大小的标签类型,这样的标签不要改变它的属性,它会使用系统的规则。

  使用系统字体创建标签:

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

标签效果

  在屏幕上有标签后,它们可能看起来很普通,这时希望让它们变得更加漂亮。不用创建自定义字体!Label对象就可以对标签应用效果,包括阴影,描边,发光。

  阴影效果:

auto myLabel = Label::createWithTTF("myFont.ttf","My Label Text",16);//所有标签类型都支持阴影效果
myLabel->enableShadow();

  描边效果:

auto myLabel = Label::createWithTTF("myFont.ttf","My Label Text",16);//描边效果仅支持TTF字体,而且需要指定所需的颜色
myLabel->enableOutline(Color4B::WHITE,1);

  发光效果:

auto myLabel = Label::createWithTTF("myFont.ttf","My Label Text",16);//发光效果仅支持TTF字体,而且需要指定所需的颜色
myLabel->enabelGlow(Color4B::YELLOW);

实例

  • 使用文本标签实现打字机效果,要求:

    • 控制每行字数自动换行
    • 文字字体使用方正姚体
    • 字体加粗
    • 字体颜色粉红色
    • 实现打字机效果
演示效果

示例代码如下
json文件

使用json文件主要是解决中文乱码的问题,详见链接:https://blog.csdn.net/qq135595696/article/details/122850029

HelloWorldScene.h
#ifndef __HELLOWORLD_SCENE_H__
#define __HELLOWORLD_SCENE_H__#include "cocos2d.h"
#include <string>class HelloWorld : public cocos2d::Scene
{public:static cocos2d::Scene* createScene();virtual bool init();// implement the "static create()" method manuallyCREATE_FUNC(HelloWorld);private://记录当前文字内容std::string prt_content;cocos2d::Label* prt_label;
};#endif // __HELLOWORLD_SCENE_H__
HelloWorldScene.cpp
#include "HelloWorldScene.h"
#include "SimpleAudioEngine.h"
#include "LayerDemo.h"
//引入cJson库文件
#include "cJSON.h"#include <fstream>//C++IO流头文件USING_NS_CC;
using namespace std;Scene* HelloWorld::createScene()
{return HelloWorld::create();
}// Print useful error message instead of segfaulting when files are not there.
static void problemLoading(const char* filename)
{printf("Error while loading: %s\n", filename);printf("Depending on how you compiled you might have to add 'Resources/' in front of filenames in HelloWorldScene.cpp\n");
}// on "init" you need to initialize your instance
bool HelloWorld::init()
{if (!Scene::init())return false;auto visibleSize = Director::getInstance()->getVisibleSize();Vec2 origin = Director::getInstance()->getVisibleOrigin();//读取test.json文件内容FILE* pFile = fopen("test.json", "r");if (nullptr == pFile){problemLoading("test.json");return false;}char testContent[1024 * 20]{ 0 };while (!feof(pFile)){char buffer[1024]{ 0 };fgets(buffer, 1024, pFile);int index = strlen(testContent);for (int i = 0; i < strlen(buffer); i++){if (buffer[i] == '\n')break;testContent[index++] = buffer[i];}}//解析test.json文件内容cJSON* monitor = cJSON_Parse(testContent);//将字符串转换为json对象if (nullptr == monitor)return false;//获取key为mainKey1的对象内容cJSON* mainKey1 = cJSON_GetObjectItem(monitor, "mainKey1");//获取key为value的对象内容auto value1 = cJSON_GetObjectItem(mainKey1, "value");//输出打印value对象的内容log(value1->valuestring);//实现背景图片auto sprite = Sprite::create("1.jpg");sprite->setAnchorPoint(Vec2::ANCHOR_MIDDLE);sprite->setPosition(Vec2(visibleSize / 2));sprite->setScale(0.3);this->addChild(sprite);//显示文字内容prt_content = value1->valuestring;//开始不显示任何内容prt_label = Label::create(prt_content, "方正姚体", 30);prt_label->setAnchorPoint(Vec2::ANCHOR_MIDDLE);prt_label->setPosition(Vec2(visibleSize / 2));prt_label->setColor(Color3B(248, 248, 255));prt_label->enableBold();prt_label->setDimensions(400.0f, 0);//使用纯英文换行失效,只有存在中文才可能生效!this->addChild(prt_label);//实现打字效果static int i = 0;this->schedule([&](float dlt) {char ch = prt_content[i];//获取当前下标的字符if (ch < 0 && ch > -128)//在utf-8编码中一个中文占三个字节,在ANSI编码中一个中文占2个字节,在utf-16中一个中文占4个字节i += 3;elsei++;//截取字符串string str = prt_content.substr(0, i);prt_label->setString(str);if (i > prt_content.length())this->unschedule("scheduleCallback");//停止定时器}, 0.1f, "scheduleCallback");return true;
}

菜单(Menu)

  • 继承自Layer类,是一个层容器

  在每个游戏中都会有菜单。我们使用菜单浏览游戏选项,更改游戏设置。菜单通常包含开始,退出,设置,关于等项,菜单当然也可以包含子菜单。在Cocos2d-x提供Menu对象支持菜单功能,Menu对象是一种特殊的Node对象。

  创建一个菜单用于添加菜单项:

auto myMenu = Menu::create();

  像我们刚才提到的一个菜单,总会有一些菜单项,比如开始,退出,设置等,没有菜单项的菜单没有存在的意义。Cocos2d-x提供了一些方法来创建菜单项,比如使用Label对象,或是使用一张图像。菜单项一般由正常状态和选择状态。菜单项显示是正常状态,当你点击时变为选择状态,同时点击菜单还会触发一个回调函数

  使用图像创建菜单:

//通过指定的图像创建菜单项
auto closeItem = MenuItemImage::create("CloseNormal.png","CloseSelected.png",CC_CALLBACK_1(HelloWorld::menuCloseCallback,this));auto menu = Menu::create(closeItem,NULL);
this->addChild(menu,1);

  还可以使用MenuItem的一个vector创建菜单:

//创建一个vector来管理menuItems
Vector<MenuItem*> MenuItems;auto closeItem = MenuItemImage::craete("CloseNormal.png","CloseSelected.png",CC_CALLBACK_1(HelloWorld::menuCloseCallback,this));MenuItems.pushBack(closeItem);auto menu = Menu::createWithArray(MenuItems);
this->addChild(menu,1);

使用Lambda表达式

  当点击菜单项时会触发一个回调函数。C++11支持了lambda表达式,lambda表达式时匿名函数,所以可以在回调方法处使用lambda表达式,这样能让代码看起来更简单,同时不会有额外的性能开销。

  一个简单的lambda表达式:

//创建一个简单的lambda表达式
auto func = [](){cout<<"Hello World";};//执行该函数
func();

  使用lambda表达式作为菜单项的回调函数:

auto closeItem = MenuItemImage::create("CloseNormal.png","CloseSelected.png",[&](Ref* sender){//执行我们需要的逻辑
});

按钮(Button)

  按钮在我们点击后会使我们的游戏产生一些变化,比如更改了场景,触发了动作等。按钮会拦截点击事件,事件触发时调用事先定义好的回调函数。按钮有一个正常状态,一个选择状态,还有一个不可点击状态,按钮的外观可以根据这三个状态而改变。Cocos2d-x提供Button对象支持按钮功能,创建一个按钮并定义一个回调函数很简单,但是需要在操作的时候要有头文件需包含:#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图像:

  在屏幕显示的时候,同一个时刻只能看到一个状态,正常显示状态像这样:

复选框(CheckBox)

  日常生活中复选框很常见,比如填写问卷时,让我们选一些喜欢的项目,游戏设置中,某一设置时打开还是关闭。只有两种状态的项目经常被设计为复选框。Cocos2d-x提供Checkbox对象支持复选框功能。

  创建一个复选框:

#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<<"check 1 clicked"<<std::endl;break;default:break;}
});this->addChild(checkbox);

  在上面的例子中,我么能看到一个复选框制定了五张图像,因为复选框有五种状态,未被选中,被点击,未被选中时不可用,被选中,选中时不可用。这样五种状态的图像依次如下:

  在频幕显示的时候,同一个时刻只能看到一个状态,被选中时状态像这样:

进度条(LoadingBar)

  如果你经常玩游戏,那肯定见过一个情景:屏幕上显示了一个进度条,提示资源正在加载中,这个条表示资源加载的进度。Cocos2d-x提供LoadingBar对象支持进度条。

  创建一个进度条:

#include "ui/CocosGUI.h"auto loadingBar = LoadingBar::create("LoadingBarFile.png");//设置进度条的加载方向
loadingBar->setDirection(LoadingBar::Direction::RIGHT);this.addChild(loadingBar);

  上面的例子,我们创建了一个进度条,设置了当进度条增加时,进度条向右填充。

  在进度的控制中,肯定需要改变进度条的进度,示例如下:

#include "ui/CocosGUI.h"auto loadingBar = LoadingBar::craete("LoadingBarFile.png");
loadingBar->setDirection(LoadingBar::Direction::RIGHT);//触发事件,改变进度条的百分比
loadingBar->setPercent(25);//再次改变
loadingBar->setPercent(35);this->addChild(loadingBar);

  上面的例子,使用的进度条图像是:

  在屏幕上一个满进度的进度条是这样的:

滑动条(Slider)

  有时候你想平滑的改变一个值,比如游戏设置中,调整背景音乐的音量,或者你有一个角色,允许用户设置攻击敌人的力量。这种场景最适合使用滑动条,Cocos2d-x提供Slider对象支持滑动条。

  创建滑动条:

#include "ui/CocosGUI.h"auto slider = Slider::create();
slider->loadBarTexture("Slider_Back.png");//滑动条看起来像什么
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);

  从上面的例子,可以看出,实现一个滑动条需要提供五张图像,对应滑动条的不同部分不同状态,分别为:滑动条背景,上层进度条,正常显示时的滑动端点,滑动式的滑动端点,不可用时的滑动端点。本次示例的五张图如下:

  在屏幕上一个滑动条看起来是这样的:

文本框(TextField)

  如果你想让参与游戏的玩家可以自定义一个昵称怎么办,在哪里输入文本?Cocos2d-x提供TextField满足这种需求。它支持触摸事件,焦点,定位内容百分比等。

  创建一个文本框:

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

  这个例子中,创建了一个TextField,指定了回调函数。

  提供的文本对象,是多功能的,能满足所有的输入需求,比如用户密码的输入,限制用户可以输入的字符数等等!

  看一个例子:

#include "ui/CocosGUI.h"auto textField = TextField::craete("","Arial",30);//启动此文本字段密码
textField->setPasswordEnabled(true);//设置用户可以输入此文本字段的最大字符数
textField->setMaxLength(10);textField->addTouchEventListener([&](Ref* sender,Widget::TouchEventType type){std::cout << "editing a TextField" << std::endl;
});this->addChild(textField);

  屏幕上一个文本框是这样的:

  当点击文本框,键盘就会自动调出来,此时可以输入文本:

Cocos2d-xUI组件详解相关推荐

  1. Android笔记——四大组件详解与总结

    android四大组件分别为activity.service.content provider.broadcast receiver. -------------------------------- ...

  2. ReactNative ViewPageAndroid组件详解

    源码传送门 在我们开发Android的时候,ViewPage这个控件的使用频率还是很高的,最简单的就是制作引导页,应用程序的主界面等,在ReactNative开发中实现该功能的组件是ViewPageA ...

  3. Android Lifecycle 生命周期组件详解

    转载请标明出处:https://blog.csdn.net/zhaoyanjun6/article/details/99695779 本文出自[赵彦军的博客] 一.Lifecycle简介 为什么要引进 ...

  4. Cinder 组件详解 - 每天5分钟玩转 OpenStack(47)

    Cinder 组件详解 - 每天5分钟玩转 OpenStack(47) 本节我们将详细讲解 Cinder 的各个子服务. cinder-api cinder-api 是整个 Cinder 组件的门户, ...

  5. Android应用开发—Intent组件详解

    转载自:Android中Intent组件详解 Intent是不同组件之间相互通讯的纽带,封装了不同组件之间通讯的条件. Intent本身是定义为一个类别(Class),一个Intent对象表达一个目的 ...

  6. ue4移动到一定距离_UE4移动组件详解(一)——移动框架与实现原理

    原文链接(转载请标明):UE4移动组件详解(一)--移动框架与实现原理_Jerish的博客-CSDN博客​blog.csdn.net 前言 关于UE4的移动组件,我写了一篇非常详细的分析文档.由于篇幅 ...

  7. SpringCloud分布式开发五大组件详解

    SpringCloud分布式开发五大组件详解 https://blog.csdn.net/weixin_40910372/article/details/89466955 服务发现--Netflix ...

  8. Tkinter 组件详解(十):Scale

    Tkinter 组件详解之Scale Scale(刻度)组件看起来像是一个带数据的 Scrollbar(滚动条)组件,但事实上它们是不同的两个东东.Scale 组件允许用于通过滑动滑块来选择一个范围内 ...

  9. Unity 之 UGUI Dropdown下拉选单组件详解

    Unity 之 UGUI Dropdown下拉选单组件详解 1,属性面板 1), Dropdown的组成 2,代码操作 3,使用实例 1), 控制菜单展开方向 4,相关扩展 1), Lua中动态添加O ...

  10. 火山PC编辑框组件详解3

    上一篇文章地址:火山PC编辑框组件详解2 一.布局 就放两个编辑框 二.添加触发事件 ①设计区添加 ②代码区添加 三.触发 ①按下和放开某键 可以直接判断键码值,不知道的,可以输出看下,或参照最后一张 ...

最新文章

  1. 一步步带你详解JVM性能调优
  2. eclipse删除perspective
  3. 把在win7系统下,把笔记本的无线网卡变成路由器,共享上网。
  4. Go语言实时GC - 三色标记算法
  5. 牛客-乃爱与城市拥挤程度【树形dp】
  6. datatable的数据进行组内排序_排序算法学习分享(四)希尔排序
  7. U盘装win7系统出现question(1808)的原因与解决方法
  8. linux webshell 页面管理,instantbox:30s内快速搭建可通过webshell管理的Linux系统
  9. jquery动态改变div宽度和高度
  10. 62. Using Default Magento Cache
  11. python rsi_使用python与rsi进行算法交易
  12. Android开发实战——计算器
  13. webx rewrite
  14. [置顶]       cocos2d-x2.2.5走四棋儿源码“开源”
  15. URL在线编码/解码工具
  16. 我的世界神奇宝贝服务器怎么修改6v,我的世界神奇宝贝mod修改精灵6V满努力等级图文教程...
  17. c++对象模型探索-王健伟-专题视频课程
  18. sqli-labs(29-31)
  19. sqli-labs(11-17)
  20. datav可视化大屏使用教程

热门文章

  1. 【论文】2019 年,智能问答(Question Answering)的主要研究方向有哪些?
  2. 数据结构与算法python—11.查找及python实现与leetcode总结
  3. numpy 常用产生随机数方法
  4. 为什么经常说Node.js不适合大型应用
  5. 从例图中学习思维导图的基本概念
  6. CSDNamp;amp;《程序员》杂志创始人——蒋涛 推荐
  7. 2.7 tf.data创建Dataset以及数据处理教程——tensorflow2
  8. Sublime Text 3安装、配置和快捷键
  9. Pytorch完成线性回归
  10. php 快速路由,基于FastRoute的快速路由(支持RESTful)