Cocos2d-x 3.9教程:7. Cocos2d-x中的控件_cocos 旋转控件-程序员宅基地

技术标签: cocos2d-x  手游  自学  3.9  教程  

Cocos2d-x 3.9教程:

7. Cocos2d-x中的控件

1.1. Button

按钮的使用,详见“4.4按钮的基本使用及9宫格缩放”。

1.2. 旋钮控件ControlPotentiometer

旋钮控件,由“底座图片”、“进度条图片”和“控制按钮图片”3部分组成。如下图:

 

在界面上的最终效果:

初始状态:

拖动时状态:

具体代码如下:

ControlPotentiometer * potentiometer = ControlPotentiometer::create("potentiometerTrack.png",

"potentiometerProgress.png", "potentiometerButton.png");

potentiometer->setPosition(Vec2(100, 200));

 

this->addChild(potentiometer);

注意,此类控件需要添加扩展库的支持:

#include "cocos-ext.h"

USING_NS_CC_EXT;

若编译时提示: fatal error C1083: 无法打开包括文件:“extensions/ExtensionMacros.h: No such file or directory”。

则还需要在项目属性上附加包含目录:

选中工程右键“属性”->"配置属性“->"c/c++"->"常规”->"附加包含目录"中添加“”$(EngineRoot)

添加响应事件:

ControlPotentiometer * potentiometer = ControlPotentiometer::create("potentiometerTrack.png",

"potentiometerProgress.png", "potentiometerButton.png");

potentiometer->setPosition(Vec2(100, 200));

potentiometer->addTargetWithActionForControlEvents(this, cccontrol_selector(HelloWorld::onValueChanged), Control::EventType::VALUE_CHANGED);

 

this->addChild(potentiometer);

 

auto showValue = Label::createWithTTF(G2U("数值:"), "fonts/abc.ttf", 24);

showValue->setTextColor(Color4B::WHITE);

showValue->setTag(1);

showValue->setPosition(Vec2(visibleSize.width / 2, visibleSize.height / 2));

 

this->addChild(showValue, 1);

void HelloWorld::onValueChanged(Ref* pSender, Control::EventType event)

{

ControlPotentiometer * potentiometer = (ControlPotentiometer*)pSender;

 

String *valueStr = String::createWithFormat("数值:%f", potentiometer->getValue());

 

Label * label = (Label*)getChildByTag(1);

label->setString(G2U(valueStr->getCString()));

}

1.3. 滑条控件-血量条ControlSlider

跟旋钮控件类似,滑条空间也是由3部分组成:“背景图片”、“进度条图片”和“控制按钮图片”。如果把“控制按钮”设为透明的,则变成了游戏中的“血槽”,类似于进度条的效果。

创建和响应事件的方式也非常的类似:

#include "cocos-ext.h"

USING_NS_CC_EXT;

ControlSlider * slider = ControlSlider::create("sliderBg.png",

"sliderValue.png", "button.png");

slider->setPosition(Vec2(100, 200));

slider->setMinimumValue(0);

slider->setMaximumValue(5000);

slider->setValue(3000);

slider->addTargetWithActionForControlEvents(this, cccontrol_selector(HelloWorld::onValueChanged), Control::EventType::VALUE_CHANGED);

 

this->addChild(slider);

 

auto showValue = Label::createWithTTF(G2U("数值:"), "fonts/abc.ttf", 24);

showValue->setTextColor(Color4B::WHITE);

showValue->setTag(1);

showValue->setPosition(Vec2(visibleSize.width / 2, visibleSize.height / 2));

 

this->addChild(showValue, 1);

void HelloWorld::onValueChanged(Ref* pSender, Control::EventType event)

{

ControlSlider * potentiometer = (ControlSlider*)pSender;

 

String *valueStr = String::createWithFormat("数值:%f", potentiometer->getValue());

 

Label * label = (Label*)getChildByTag(1);

label->setString(G2U(valueStr->getCString()));

}

最终效果如下:

 

1.4. CheckBox复选框控件

复选框控件,由“背景图片”和“勾选图片”组成,类似“□”和“√”。创建和使用也非常简单,如下列代码:

#include "ui/UICheckBox.h"

CheckBox * checkBox = CheckBox::create("check_box_bg.png", "check_box_cross.png");

checkBox->setPosition(Vec2(visibleSize.width / 2, visibleSize.height / 2 - 150));

checkBox->addCCSEventListener(CC_CALLBACK_2(HelloWorld::onCheckBox, this));

this->addChild(checkBox);

 

auto showValue = Label::createWithTTF(G2U("状态"), "fonts/abc.ttf", 24);

showValue->setTextColor(Color4B::WHITE);

showValue->setTag(1);

showValue->setPosition(Vec2(visibleSize.width / 2, visibleSize.height / 2));

this->addChild(showValue, 1);

void HelloWorld::onCheckBox(Ref* pSender, int checkEvent)

{

Label * label = (Label*)getChildByTag(1);

 

if (checkEvent == CheckBoxEventType::CHECKBOX_STATE_EVENT_SELECTED)

{

label->setString(G2U("选中!"));

}

else if (checkEvent == CheckBoxEventType::CHECKBOX_STATE_EVENT_UNSELECTED)

{

label->setString(G2U("未选中!"));

}

}

1.5. 简单滑条控件Slider

简单滑条控件Slider是相对于ControlSlider来说,其功能和组成都较为简单。其界面只是由“背景图片”和“控制按钮图片”两部分组成。数值范围为百分比,在0到100之间变化。

#include "ui/UISlider.h"

Slider *slider = Slider::create("sliderBg.png", "button.png");

slider->setPosition(Vec2(visibleSize.width / 2, 200));

slider->addCCSEventListener(CC_CALLBACK_2(HelloWorld::onValueChanged, this));

this->addChild(slider);

 

auto showValue = Label::createWithTTF(G2U("数值:"), "fonts/abc.ttf", 24);

showValue->setTextColor(Color4B::WHITE);

showValue->setTag(1);

showValue->setPosition(Vec2(visibleSize.width / 2, visibleSize.height / 2));

 

this->addChild(showValue);

void HelloWorld::onValueChanged(Ref* pSender, int event)

{

Slider * slider = (Slider*)pSender;

 

String *valueStr = String::createWithFormat("数值:%d", slider->getPercent());

 

Label * label = (Label*)getChildByTag(1);

label->setString(G2U(valueStr->getCString()));

}

最终效果:

1.6. 进度条控件LoadingBar

进度条控件仅仅只有背景图片,默认从左向右增长,值从0.0f到100.0f增长,为百分比。创建和使用也比较简单:

#include "ui/UILoadingBar.h"

LoadingBar *loadingBar = LoadingBar::create("sliderBg.png", 50);

//loadingBar->setDirection(LoadingBar::Direction::RIGHT);//默认从左向右增长,用RIGHT则从右向左增长

loadingBar->setPosition(Vec2(visibleSize.width / 2, 200));

loadingBar->setTag(100);

this->addChild(loadingBar);

 

auto showValue = Label::createWithTTF(G2U("数值:"), "fonts/abc.ttf", 24);

showValue->setTextColor(Color4B::WHITE);

showValue->setTag(1);

showValue->setPosition(Vec2(visibleSize.width / 2, visibleSize.height / 2));

 

this->addChild(showValue);

 

this->schedule(CC_SCHEDULE_SELECTOR(HelloWorld::onSchedule), 0.1f);

void HelloWorld::onSchedule(float time)

{

LoadingBar * loadingBar = (LoadingBar*)getChildByTag(100);

float percent = loadingBar->getPercent();

if (percent <= 99.0f)

{

percent += 1;

loadingBar->setPercent(percent);

 

String *valueStr = String::createWithFormat("数值:%.2f", loadingBar->getPercent());

 

Label * label = (Label*)getChildByTag(1);

label->setString(G2U(valueStr->getCString()));

}

else

{

this->unschedule(CC_SCHEDULE_SELECTOR(HelloWorld::onSchedule));

}

}

最终效果:

 

1.7. 字符图集TextAtlas

字符图集,也就是将图形化的文字放到一个文件中,按照非常规则的方式排列,然后给出每个“图文”所占的宽、高像素数,然后拿一个“字符映射集合”(其实就是一个字符串)来对应每个图文。在绘制时,根据所需要显示的字符串,来从中找出相应的图文拼接成图片显示出来!

创建和使用非常的简单:

#include "ui/UITextAtlas.h"

TextAtlas * textAtlas = TextAtlas::create("0123456789", "atlas.png", 140, 140, "0");

textAtlas->setString("0");

//textAtlas->setStringValue("0");

textAtlas->setPosition(Vec2(visibleSize.width / 2, 200));

textAtlas->setTag(1);

this->addChild(textAtlas);

 

this->schedule(CC_SCHEDULE_SELECTOR(HelloWorld::onSchedule), 0.1f);

void HelloWorld::onSchedule(float time)

{

TextAtlas * textAtlas = (TextAtlas *)getChildByTag(1);

string strValue = textAtlas->getString();

 

int value = atoi(strValue.c_str());

 

if (value < 100)

value++;

else

value = 0;

 

stringstream ss;

ss << value;

string s1 = ss.str();

 

textAtlas->setString(s1.c_str());

}

上面的代码功能是每隔0.1秒,显示一个逐步+1操作的数字,范围从0到100,循环显示。

最终效果如下:

1.8. Label文本标签控件

cocos2d-x中,提供了功能强大的Label控件,让我们简单的加载各种格式的字体,按照我们想要的效果来显示一段文字。同时,Label提供了按最大行宽自动换行、设置颜色、设置阴影、描边、发光三个特效。

①基本使用

我们在场景cpp文件的init()方法中最后部分添加以下代码:

bool HelloWorld::init()

{

//原有代码//

//函数最后部分添加///

Label * label = Label::createWithTTF("", "fonts/arial.ttf", 24);

label->setString("aaaaaaaaaaaaaaaaabbbbbbbbbbbbbbbbbbbbbbbbbcccccccccccccccccccccdddddddddddddddeeeeeeeeeeeeeeee");

label->setLineBreakWithoutSpace(true);//开启自动换行

label->setMaxLineWidth(visibleSize.width - 200);//设置自动换行时的最大行宽

label->setPosition(Vec2(visibleSize.width / 2, visibleSize.height / 2 + 100));

label->setName("label");

addChild(label);

return true;

}

运行时效果如下:

注意,系统默认字体是无法自动换行的,即便我们设定了相关属性。

②阴影效果

我们在上小节“①基本使用”的代码基础上,添加阴影效果:

label->enableShadow(Color4B::GREEN, Size(10, -5));

第一个参数为阴影的颜色,第二个参数为阴影相对于原文字的偏移量。

运行时效果如下:

③描边、轮廓

我们在上小节“①基本使用”的代码基础上,添加描边效果:

label->enableOutline(Color4B::RED, 3);

第一个参数为描边的颜色,第二个参数为描边的宽度。

运行时效果如下:

④发光

我们在上小节“①基本使用”的代码基础上,添加发光效果:

label->enableGlow(Color4B::RED);

第一个参数为发光的颜色。

运行时效果如下:

在原有文字的周围有淡淡的发光颜色。注意,Glow发光从某种角度来讲就是一种特殊的OutLine描边。因此Glow发光和OutLine效果只能显示一种,不能同时起效。

⑤获取单个字母

Label还提供一个非常强大的功能,我们可以获取某一个字母,获取的同时会转换成Sprite精灵对象,然后再操作它:

Label * label = Label::createWithTTF("", "fonts/arial.ttf", 24);

label->setString("Hello Label!");

label->setHeight(200);

label->setLineBreakWithoutSpace(true);//开启自动换行

label->setMaxLineWidth(visibleSize.width - 200);//设置自动换行时的最大行宽

label->setPosition(Vec2(visibleSize.width / 2, visibleSize.height / 2));

label->setName("label");

 

addChild(label);

 

Sprite * letterH = label->getLetter(0);

letterH->setColor(Color3B::BLUE);

 

Sprite * letterL = label->getLetter(6);

letterL->setColor(Color3B::RED);

letterL->runAction(RepeatForever::create(RotateBy::create(1, 360)));

运行效果如下:

上述代码中,我们把第0个(下标)字母H设置为蓝色,把第6个字母(下标)设置为红色,并且执行旋转动作(动作Action参见后续章节)。

1.9. Text简单文本控件

简单的根据字体和内容显示一段文字,但暂未找到如何设置文字间距和行间距。

#include "ui/UIText.h"

Text * text = Text::create(G2U("以前人们在四月开始收获\

\n躺在高高的谷堆上面笑着\n我穿过金黄的麦田\n去给稻草人唱歌\n等着落山风吹过"), "fonts/abc.ttf", 24);

text->setTextHorizontalAlignment(TextHAlignment::CENTER);//水平居中

text->setPosition(Vec2(visibleSize.width / 2, visibleSize.height / 2 + text->getContentSize().height / 2));

this->addChild(text);

最终效果如下:

1.10. 字符串编辑控件TextField

TextField是一种字符串编辑控件,可以在其中输入文字,还可以跟当前操作系统下的输入法进行交互。但目前发现其不能换行。

#include "ui/UITextField.h"

TextField *textField = TextField::create(G2U("文字输入测试!"), "fonts/abc.ttf", 24);

textField->setPosition(Vec2(100, 100));

//textField->setPasswordEnabled(true);//作为密码只显示“*”

//textField->setPasswordStyleText("x");//修改密码样式(默认为“*”)

//textField->setMaxLengthEnabled(true);//开启限定最大长度

//textField->setMaxLength(10);//最大长度10个字符,后面无法继续输入

textField->addEventListener(CC_CALLBACK_2(HelloWorld::onTextFieldEvent, this));

this->addChild(textField);

void HelloWorld::onTextFieldEvent(Ref* pSender, TextField::EventType event)

{

switch (event)

{

case TextField::EventType::ATTACH_WITH_IME:

TextField * textField = dynamic_cast<TextField*>(pSender);

Size screenSize = Director::getInstance()->getWinSize();

textField->runAction(MoveTo::create(0.225f,

Point(screenSize.width/2.0f, screenSize.height/2.0f+textField->getContentSize().height/2.0f)));

break;

}

}

最终效果:

1.11. 字符串编辑框控件EditBox

编辑框,由底部图片(实际上是一个九宫格精灵)和其上的字符串组成。作用是在点击时弹出窗口来输入文字。我们可以把它用作类似于手机聊天窗口中的气泡显示样式。

#include "ui/UIEditBox/UIEditBox.h"

cocos2d::ui::Scale9Sprite *s9p = cocos2d::ui::Scale9Sprite::create("chat_bubble.png");

s9p->setCapInsets(CCRect(32, 32, 90, 90));//10,10决定了左上角那一格的大小,263,40是中心那一格的宽和高

s9p->setPreferredSize(CCSize(300, 150));//设定“建议尺寸”,即是拉伸后的尺寸

s9p->setPosition(400, 500);

cocos2d::ui::EditBox * editBox = cocos2d::ui::EditBox::create(Size(300, 100), s9p);

editBox->setContentSize(Size(200, 100));

editBox->setPosition(Vec2(visibleSize.width / 2, visibleSize.height / 2));

editBox->setFont("fonts/abc.ttf", 24);

editBox->setFontColor(Color4B::WHITE);

editBox->setInputMode(cocos2d::ui::EditBox::InputMode::DECIMAL);

//editBox->setInputFlag(cocos2d::ui::EditBox::InputFlag::PASSWORD);//显示为密码

editBox->setPlaceHolder(G2U("点击输入"));

editBox->setDelegate(this);//绑定委托对象,来处理响应事件

this->addChild(editBox,1);

在此需要注意,EditBox不是通过callback来回调方法的,而是通过委托来实现响应事件的。因此,需要委托类继承EditBoxDelegate抽象类:

class HelloWorld : public cocos2d::Layer, public cocos2d::ui::EditBoxDelegate

{

………………

virtual void editBoxReturn(cocos2d::ui::EditBox* editBox);

virtual void editBoxTextChanged(cocos2d::ui::EditBox* editBox, const std::string& text);

virtual void editBoxEditingDidBegin(cocos2d::ui::EditBox* editBox);

virtual void editBoxEditingDidEnd(cocos2d::ui::EditBox* editBox);

}

//在editBox中按下回车键会响应该函数

void HelloWorld::editBoxReturn(cocos2d::ui::EditBox* editBox)

{

CCLOG("return pressed!");

}

 

void HelloWorld::editBoxTextChanged(cocos2d::ui::EditBox* editBox, const std::string& text)

{

//使用一个临时的Label,用于测量字符串实际占的大小

Label * tempLabel = Label::createWithTTF(text, "fonts/abc.ttf", 24);

 

Size origin = editBox->getContentSize();

origin.width = tempLabel->getContentSize().width + 182;

editBox->setContentSize(origin);

}

 

void HelloWorld::editBoxEditingDidBegin(cocos2d::ui::EditBox* editBox)

{

CCLOG("edit box text begin editing!");

}

void HelloWorld::editBoxEditingDidEnd(cocos2d::ui::EditBox* editBox)

{

CCLOG("edit box text end editing!");

}

最后一定要注意,由于老版cocos2d-x中的EditBox是放在cocos2d::extension::EditBox中的,因此在使用EditBox类时,最好用完全的路径名,如:cocos2d::ui::EditBox。因为若我们包含了extension扩展库,则在编译时要么报错(二义性,不知道用哪个EditBox),要么不报错却使用了扩展库中的EditBox从而导致运行结果不正确!

最终效果如下:

 

注意,上图中的背景图片大小,并不会根据内容来调整大小。我们上述例子中,是重载了editBoxTextChanged方法,在其中根据字符串的内容来调整气泡大小来实现动态调整的。字符串增长后,效果如下:

 

版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://blog.csdn.net/tiancao222/article/details/51050303

智能推荐

纯前端使用xlsx-js-style实现带样式表格导出_xlsx-style 下载-程序员宅基地

文章浏览阅读805次,点赞3次,收藏2次。最近接到一个新的需求是纯前端导出并且携带样式,也踩过了许多的坑1.xlsx开源版只能实现导出不能携带样式2.xlsx-style可以实现样式,但是弊端是:步骤麻烦、添加多Sheet页也麻烦3.xlsx-js-style结合xlsx和xlsx-js的免费插件,步骤简单,可实现纯前端带样式和多Sheet页导出。_xlsx-style 下载

Spark学习之driver_spark driver什么时候创建-程序员宅基地

文章浏览阅读9.5k次,点赞13次,收藏47次。driver在spark中并不是一个非常重要的概念,但是在学习过程中对于他的理解感觉比其他组件都要费劲,花了几天的功夫终于把Driver弄明白了,希望这篇博客能对刚学习spark的人有点帮助因为driver这个概念的理解与spark的运行模式有关,所以在讲解spark之前会先讲一下spark的四种分布式运行模式spark的四种分布式运行模式 如图所示,上方为spark的架构图,s_spark driver什么时候创建

编写REST风格接口的注意点_平时写的接口是不是rest风格-程序员宅基地

文章浏览阅读1.9k次。https://blog.csdn.net/houjixin/article/details/54315835就看这篇文章等待过两天总结。写了大概半年的restful接口,但是没有注意其中的注意点。多注意这些细节,你才能进步。..._平时写的接口是不是rest风格

Tomcat 七 HTTP 连接器-程序员宅基地

文章浏览阅读179次。摘要本文尝试翻译Tomcat官方文档Apache Tomcat 7连接器,不足之处敬请指正。该文先介绍了Tomcat7 HTTP连接器的属性,包括:公共属性、标准实现、Java TCP套接字属性、BIO的具体配置、NIO的具体配置、APR/Native的具体配置。接着介绍了Tomcat的特殊功能,包括:HTTP/1.1和HTTP/1.0的支持、代理支持、SSL支持以及连接器的比较。..._tomcat http 连接器

IIS6(Win2003) 使用.net 4.0 后,默认文档失效解决方案。-程序员宅基地

文章浏览阅读105次。IIS6(Win2003) 使用.net framework 4.0 后,默认文档失效解决方案。用.net framework 4.0 开发的WEB项目,但放到iis6 中无法使用默认文档,状况如下:地址栏输入:http://xxx.xxx.xxx.xxx/ 提示找不到文件输入全称:http://xxx.xxx.xxx.xxx/default.aspx 正常显示。本人解决方..._iis6 .net 4.0 default document

实验10-7 递归求Fabonacci数列 (10 分)_函数f应返回第n个fabonacci数。题目保证输入输出在长整型范围内。建议用递归实现。-程序员宅基地

文章浏览阅读2.1k次。本题要求实现求Fabonacci数列项的函数。Fabonacci数列的定义如下:f(n)=f(n−2)+f(n−1)(n≥2),其中f(0)=0,f(1)=1。函数接口定义:int f( int n );函数f应返回第n个Fabonacci数。题目保证输入输出在长整型范围内。建议用递归实现。裁判测试程序样例:#include <stdio.h>int f( int n );int main(){ int n; scanf("%d", &a._函数f应返回第n个fabonacci数。题目保证输入输出在长整型范围内。建议用递归实现。

随便推点

将华氏温度转换成摄氏温度_android studio怎么将华氏温度转换为摄氏度-程序员宅基地

文章浏览阅读3.4k次。写一个将华氏温度转换成摄氏温度的程序,转换的公式是: °F = (9/5)*°C + 32其中C表示摄氏温度,F表示华氏温度。程序的输入是一个整数,表示华氏温度。输出对应的摄氏温度,也是一个整数。提示,为了把计算结果的浮点数转换成整数,需要使用下面的表达式: (int)x;其中x是要转换的那个浮点数。输入格式:_android studio怎么将华氏温度转换为摄氏度

串行通信/并行通信和UART、SPI、I2C、USB以及TTL、CMOS、RS-232、RS-485区别详细整理_串口与usb,spi通信有啥区别-程序员宅基地

文章浏览阅读1.8w次,点赞23次,收藏222次。串行通信/并行通信和UART、SPI、I2C、USB以及TTL、RS-232、RS-485区别详细整理串行通信/并行通信和UART口/USB口以及TTL、RS-232、RS-485这些和通信相关的名词我们做电子的每天都在接触,但是如果不认真整理,我想很多人都不知道这些名词的具体含义和区别,因为我项目中刚好需要用到UART传输数据,所以就打算用这篇文章好好的归纳一下这些磨人的“通信名词”关于串行..._串口与usb,spi通信有啥区别

【记录】easyexcel导出后打开文件报已损坏_导出exel,本地好使,服务器显示文件损坏-程序员宅基地

文章浏览阅读6.2k次。本地导出excel没问题,在linux服务器导出的excel文件是损坏的。1、导出数据可能是空的。2、linux 下可能没有权限创建临时文件,赋权限chmod 777 就可以了_导出exel,本地好使,服务器显示文件损坏

mac上mysql5.6.42 开启报错 ERROR! Couldn't find MySQL server (/usr/local/mysql/bin/mysqld_safe)_mysql error!couldn-程序员宅基地

文章浏览阅读5.9w次,点赞6次,收藏12次。 1,突发奇想在 Mac上安装一发mysql 玩一玩 突然启动的时候报错 顿时疯狂找度娘 结果找来找去 也耽搁时间 最后还是在一篇博客找到了2.mysql 的安装见 https://blog.csdn.net/dongdong9223/article/details/80722654 博客捎带提一嘴 这个安装 总体来讲没多大难度 可是当我在mysql目录下启动时候 sudo ..._mysql error!couldn

openssl x509 证书命令-程序员宅基地

文章浏览阅读810次。openssl x509命令具以下的一些功能,例如输出证书信息,签署证书请求文件、生成自签名证书、转换证书格式等。openssl x509工具不会使用openssl配置文件中的设定,而是完全需要自行设定或者使用该伪命令的默认值,它就像是一个完整的小型的CA工具箱。#主要选项:-in filename : #指定证书输入文件,若同时指定了"-req"选项,则表示输入文件为证书请求文件。-out filename : #指定输出文件-...

jmeter(性能测试):JDBC Connection Configuration与JDBC Request(连接linux数据库,查看cup,压力测试)_linux jdbc测试插件-程序员宅基地

文章浏览阅读153次。首先启动linux系统第一步:创建JDBC Connection Configuration(用于连接绑定数据库)(要开启linux中mysql的远程接口mysql下载与开启远程接口)第二步:编辑JDBC Connection Configurationjdbc:mysql://127.0.0.1:3306/app01?serverTimezone=UTC第三步:创建JDBC Request连接JDBC Connection Configuration绑定的数据库,进行操作(增删_linux jdbc测试插件