按钮的使用,详见“4.4按钮的基本使用及9宫格缩放”。
旋钮控件,由“底座图片”、“进度条图片”和“控制按钮图片”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()));
}
跟旋钮控件类似,滑条空间也是由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()));
}
最终效果如下:
复选框控件,由“背景图片”和“勾选图片”组成,类似“□”和“√”。创建和使用也非常简单,如下列代码:
#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("未选中!"));
}
}
简单滑条控件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()));
}
最终效果:
进度条控件仅仅只有背景图片,默认从左向右增长,值从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));
}
}
最终效果:
字符图集,也就是将图形化的文字放到一个文件中,按照非常规则的方式排列,然后给出每个“图文”所占的宽、高像素数,然后拿一个“字符映射集合”(其实就是一个字符串)来对应每个图文。在绘制时,根据所需要显示的字符串,来从中找出相应的图文拼接成图片显示出来!
创建和使用非常的简单:
#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,循环显示。
最终效果如下:
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参见后续章节)。
简单的根据字体和内容显示一段文字,但暂未找到如何设置文字间距和行间距。
#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);
最终效果如下:
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;
}
}
最终效果:
编辑框,由底部图片(实际上是一个九宫格精灵)和其上的字符串组成。作用是在点击时弹出窗口来输入文字。我们可以把它用作类似于手机聊天窗口中的气泡显示样式。
#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方法,在其中根据字符串的内容来调整气泡大小来实现动态调整的。字符串增长后,效果如下:
文章浏览阅读805次,点赞3次,收藏2次。最近接到一个新的需求是纯前端导出并且携带样式,也踩过了许多的坑1.xlsx开源版只能实现导出不能携带样式2.xlsx-style可以实现样式,但是弊端是:步骤麻烦、添加多Sheet页也麻烦3.xlsx-js-style结合xlsx和xlsx-js的免费插件,步骤简单,可实现纯前端带样式和多Sheet页导出。_xlsx-style 下载
文章浏览阅读9.5k次,点赞13次,收藏47次。driver在spark中并不是一个非常重要的概念,但是在学习过程中对于他的理解感觉比其他组件都要费劲,花了几天的功夫终于把Driver弄明白了,希望这篇博客能对刚学习spark的人有点帮助因为driver这个概念的理解与spark的运行模式有关,所以在讲解spark之前会先讲一下spark的四种分布式运行模式spark的四种分布式运行模式 如图所示,上方为spark的架构图,s_spark driver什么时候创建
文章浏览阅读1.9k次。https://blog.csdn.net/houjixin/article/details/54315835就看这篇文章等待过两天总结。写了大概半年的restful接口,但是没有注意其中的注意点。多注意这些细节,你才能进步。..._平时写的接口是不是rest风格
文章浏览阅读179次。摘要本文尝试翻译Tomcat官方文档Apache Tomcat 7连接器,不足之处敬请指正。该文先介绍了Tomcat7 HTTP连接器的属性,包括:公共属性、标准实现、Java TCP套接字属性、BIO的具体配置、NIO的具体配置、APR/Native的具体配置。接着介绍了Tomcat的特殊功能,包括:HTTP/1.1和HTTP/1.0的支持、代理支持、SSL支持以及连接器的比较。..._tomcat http 连接器
文章浏览阅读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
文章浏览阅读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数。题目保证输入输出在长整型范围内。建议用递归实现。
文章浏览阅读3.4k次。写一个将华氏温度转换成摄氏温度的程序,转换的公式是: °F = (9/5)*°C + 32其中C表示摄氏温度,F表示华氏温度。程序的输入是一个整数,表示华氏温度。输出对应的摄氏温度,也是一个整数。提示,为了把计算结果的浮点数转换成整数,需要使用下面的表达式: (int)x;其中x是要转换的那个浮点数。输入格式:_android studio怎么将华氏温度转换为摄氏度
文章浏览阅读1.8w次,点赞23次,收藏222次。串行通信/并行通信和UART、SPI、I2C、USB以及TTL、RS-232、RS-485区别详细整理串行通信/并行通信和UART口/USB口以及TTL、RS-232、RS-485这些和通信相关的名词我们做电子的每天都在接触,但是如果不认真整理,我想很多人都不知道这些名词的具体含义和区别,因为我项目中刚好需要用到UART传输数据,所以就打算用这篇文章好好的归纳一下这些磨人的“通信名词”关于串行..._串口与usb,spi通信有啥区别
文章浏览阅读6.2k次。本地导出excel没问题,在linux服务器导出的excel文件是损坏的。1、导出数据可能是空的。2、linux 下可能没有权限创建临时文件,赋权限chmod 777 就可以了_导出exel,本地好使,服务器显示文件损坏
文章浏览阅读5.9w次,点赞6次,收藏12次。 1,突发奇想在 Mac上安装一发mysql 玩一玩 突然启动的时候报错 顿时疯狂找度娘 结果找来找去 也耽搁时间 最后还是在一篇博客找到了2.mysql 的安装见 https://blog.csdn.net/dongdong9223/article/details/80722654 博客捎带提一嘴 这个安装 总体来讲没多大难度 可是当我在mysql目录下启动时候 sudo ..._mysql error!couldn
文章浏览阅读810次。openssl x509命令具以下的一些功能,例如输出证书信息,签署证书请求文件、生成自签名证书、转换证书格式等。openssl x509工具不会使用openssl配置文件中的设定,而是完全需要自行设定或者使用该伪命令的默认值,它就像是一个完整的小型的CA工具箱。#主要选项:-in filename : #指定证书输入文件,若同时指定了"-req"选项,则表示输入文件为证书请求文件。-out filename : #指定输出文件-...
文章浏览阅读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测试插件