本篇博客出自阿修罗道,转载请注明出处:http://blog.csdn.net/fansongy/article/details/12795299
1、概述
上篇说到将CocoStudio的导出文件在程序中运行出来,但是并没有用户交互,即点击响应,程序的逻辑判断也都没有。这篇中我们把它们加进去,这样就可以算一个完整的程序了。先上个图:
运行后,点击开始,进度条,数字增加,通过slider可以调整进度条增长的速度。
2、界面编辑
大部分界面编辑都在CocoStudio中完成,怎么编辑可以参照:
Cocos2d-x 3.0 开发(四)使用CocoStudio创建UI并载入到程序中
。
现在我们要做的工作是将所需要交互控件的Tag记下来,这样我们可以通过Tag找到这个控件。
将Tag整理后我将其记录到一个.h文件中这样在工程中就可以使用了:
const int UI_BUTTON_CLEAR = 8;
const int UI_BUTTON_START = 9;
const int UI_SLIDER_SPEED = 10;
const int UI_LOADINGBAR_LOADING = 3;
const int UI_LABELATLAS_LIFENUM = 7;
由于此处tag是CocoStudio自己生成的,所以跟大家自己可能不一样,要根据自己的进行更改。
记录好之后导出文件到我们的工程中。
3、程序关联
关联的核心在于设置响应函数、读取与改变控件状态。
首先,我在init中将Layout读入,存储为类的成员变量m_layout。不太会弄的同学可参考上一篇博客。
1、响应函数的设置
按钮是要有响应函数的,由于它是UIWidget的一个子类,所以采用的是TouchEvent的回调方式,看不太明白的同学可以参考:
Cocos2d-x 3.0开发(三)点击交互的四种处理
。//定义
void touchButton(Object* obj, TouchEventType eventType);
//挂载
Button* startBtn = dynamic_cast<Button*>(m_layout->getChildByTag(UI_BUTTON_START));
startBtn->addTouchEventListener(this,toucheventselector(HelloWorld::touchButton));
Button* pauseBtn = dynamic_cast<Button*>(m_layout->getChildByTag(UI_BUTTON_CLEAR));
pauseBtn->addTouchEventListener(this,toucheventselector(HelloWorld::touchButton));
// 实现
void HelloWorld::touchButton(Object* obj, gui::TouchEventType eventType)
{
auto button = dynamic_cast<Button*>(obj);
int tag = button->getTag();
switch(eventType)
{
case TouchEventType::TOUCH_EVENT_ENDED:
if(tag == UI_BUTTON_START)
{
changeRunning();
}
else
{
clearRunning();
}
}
}
值得注意的是这个场景中有两个按钮,我们可以采用Tag来进行区分。
2、控件的读取与更改
对于进度条和数字,我们需要做的是读取它的状态,并对它进行改变。在这个例子中我们需要在schedule的回调函数中做。Schedule的相关知识比较简单,此处不做讨论,有兴趣的同学可查阅其他资料。
void HelloWorld::runningSchedule(float dt)
{
int speed = dynamic_cast<Slider*>(m_layout->getChildByTag(UI_SLIDER_SPEED))->getPercent();
auto loadingBar = dynamic_cast<LoadingBar*>(m_layout->getChildByTag(UI_LOADINGBAR_LOADING));
int prc = loadingBar->getPercent() + speed / 15;
if(prc > 100)
{
prc = 1;
}
loadingBar->setPercent(prc);
auto numLabel = dynamic_cast<TextAtlas*>(m_layout->getChildByTag(UI_LABELATLAS_LIFENUM));
int num = atoi(numLabel->getStringValue().c_str());
num++;
char buff[100];
sprintf_s(buff,"%d",num);
numLabel->setStringValue(buff);
}
void HelloWorld::clearRunning()
{
if(m_isRunning)
{
changeRunning();
}
dynamic_cast<TextAtlas*>(m_layout->getChildByTag(UI_LABELATLAS_LIFENUM))->setStringValue("1");
dynamic_cast<LoadingBar*>(m_layout->getChildByTag(UI_LOADINGBAR_LOADING))->setPercent(1);
dynamic_cast<Slider*>(m_layout->getChildByTag(UI_SLIDER_SPEED))->setPercent(1);
}
void HelloWorld::changeRunning()
{
if(m_isRunning)
{
//pause
this->unschedule(schedule_selector(HelloWorld::runningSchedule));
m_isRunning = false;
Button* button = dynamic_cast<Button*>(m_layout->getChildByTag(UI_BUTTON_START));
button->setTitleText("运行");
}
else
{
//start
this->schedule(schedule_selector(HelloWorld::runningSchedule));
m_isRunning = true;
Button* button = dynamic_cast<Button*>(m_layout->getChildByTag(UI_BUTTON_START));
button->setTitleText("暂停");
}
}
编译运行,即可看到效果啦。
4、总结
通过建立一个Tag的索引表来找到UI中的控件资源,然后取到对其进行操作。这其中可能会有的问题是,如果多个UI控件被加载Tag可能会重复,大家要注意这点。希望cocoStudio在未来的版本中能够将Tag索引表导出成资源的.h文件。
5、本人对项目的总结
#ifndef __HELLOWORLD_SCENE_H__
#define __HELLOWORLD_SCENE_H__
#include "cocos2d.h"
#include "CocosGUI.h"
#include "cocostudio/CocoStudio.h"
using namespace cocos2d; // cocos2d-x 3.0 不建议使用 [USING_NS_CC;]
using namespace gui;
using namespace cocostudio;
class HelloWorld : public cocos2d::Layer
{
public:
// there's no 'id' in cpp, so we recommend returning the class instance pointer
static cocos2d::Scene* createScene();
// Here's a difference. Method 'init' in cocos2d-x returns bool, instead of returning 'id' in cocos2d-iphone
virtual bool init();
// a selector callback
void menuCloseCallback(Object* pSender);
// implement the "static create()" method manually
CREATE_FUNC(HelloWorld);
HelloWorld();
void touchButton(Object* obj, cocos2d::gui::TouchEventType eventType);
void runningSchedule(float dt);
private:
void clearRunning();
void changeRunning();
void changeSpeed(int speed);
bool m_isRunning;
Layout* m_layout;
};
#endif // __HELLOWORLD_SCENE_H__
#include "HelloWorldScene.h"
const int UI_BUTTON_CLEAR = 11;
const int UI_BUTTON_START = 10;
const int UI_SLIDER_SPEED = 9;
const int UI_LOADINGBAR_LOADING = 6;
const int UI_LABELATLAS_LIFENUM = 5;
//! convert from wstring to UTF8 using self-coding-converting
void WStrToUTF8(std::string& dest, const std::wstring& src){
dest.clear();
for (size_t i = 0; i < src.size(); i++){
wchar_t w = src[i];
if (w <= 0x7f)
dest.push_back((char)w);
else if (w <= 0x7ff)
{
dest.push_back(0xc0 | ((w >> 6)& 0x1f));
dest.push_back(0x80| (w & 0x3f));
}
else if (w <= 0xffff)
{
dest.push_back(0xe0 | ((w >> 12)& 0x0f));
dest.push_back(0x80| ((w >> 6) & 0x3f));
dest.push_back(0x80| (w & 0x3f));
}
else if (sizeof(wchar_t) > 2 && w <= 0x10ffff)
{
dest.push_back(0xf0 | ((w >> 18)& 0x07)); // wchar_t 4-bytes situation
dest.push_back(0x80| ((w >> 12) & 0x3f));
dest.push_back(0x80| ((w >> 6) & 0x3f));
dest.push_back(0x80| (w & 0x3f));
}
else
dest.push_back('?');
}
}
//! simple warpper
std::string WStrToUTF8(const std::wstring& str)
{
std::string result;
WStrToUTF8(result, str);
return result;
}
HelloWorld::HelloWorld():
m_isRunning(false)
{
}
Scene* HelloWorld::createScene()
{
// 'scene' is an autorelease object
auto scene = Scene::create();
// 'layer' is an autorelease object
auto layer = HelloWorld::create();
// add layer as a child to scene
scene->addChild(layer);
// return the scene
return scene;
}
// on "init" you need to initialize your instance
bool HelloWorld::init()
{
//////////////////////////////
// 1. super init first
if ( !Layer::init() )
{
return false;
}
Size visibleSize = Director::getInstance()->getVisibleSize();
Point origin = Director::getInstance()->getVisibleOrigin();
/////////////////////////////
// 2. add a menu item with "X" image, which is clicked to quit the program
// you may modify it.
// add a "close" icon to exit the progress. it's an autorelease object
auto closeItem = MenuItemImage::create(
"CloseNormal.png",
"CloseSelected.png",
CC_CALLBACK_1(HelloWorld::menuCloseCallback, this));
closeItem->setPosition(Point(origin.x + visibleSize.width - closeItem->getContentSize().width/2 ,
origin.y + closeItem->getContentSize().height/2));
// create menu, it's an autorelease object
auto menu = Menu::create(closeItem, NULL);
menu->setPosition(Point::ZERO);
this->addChild(menu, 1);
/////////////////////////////
// 3. add your codes below...
// add a label shows "Hello World"
// create and initialize a label
// cocos2d-x 3.0 beta
Layer * layer = Layer::create();
m_layout = dynamic_cast<Layout*>(cocostudio::GUIReader::getInstance()->widgetFromJsonFile("testUI\\testUI.ExportJson"));
// myLayout->setPosition(Point(origin.x + visibleSize.width/2 - myLayout->getContentSize().width/2,
// origin.y + visibleSize.height/2 - myLayout->getContentSize().height/2));
layer->addChild(m_layout);
this->addChild(layer);
////////// 获取数字标签 ///////////////
TextAtlas* labelNum = dynamic_cast<TextAtlas*>(m_layout->getChildByTag(UI_LABELATLAS_LIFENUM));
labelNum->setStringValue("1");
////////// 获取开始按钮 ///////////////
Button* startBtn = dynamic_cast<Button*>(m_layout->getChildByTag(UI_BUTTON_START));
startBtn->addTouchEventListener(this,toucheventselector(HelloWorld::touchButton));
////////// 获取清除按钮 ///////////////
Button * clearBtn = dynamic_cast<Button*>(m_layout->getChildByTag(UI_BUTTON_CLEAR));
clearBtn->addTouchEventListener(this, toucheventselector(HelloWorld::touchButton));
return true;
}
void HelloWorld::touchButton(Object* obj, gui::TouchEventType eventType)
{
auto button = dynamic_cast<Button*>(obj);
int tag = button->getTag();
switch(eventType)
{
case TouchEventType::TOUCH_EVENT_ENDED:
if(tag == UI_BUTTON_START)
{
changeRunning();
}
else
{
clearRunning();
}
}
}
void HelloWorld::clearRunning()
{
if(m_isRunning)
{
changeRunning();
}
dynamic_cast<TextAtlas*>(m_layout->getChildByTag(UI_LABELATLAS_LIFENUM))->setStringValue("1");
dynamic_cast<LoadingBar*>(m_layout->getChildByTag(UI_LOADINGBAR_LOADING))->setPercent(1);
dynamic_cast<Slider*>(m_layout->getChildByTag(UI_SLIDER_SPEED))->setPercent(1);
}
void HelloWorld::changeRunning()
{
if(m_isRunning)
{
//pause
this->unschedule(schedule_selector(HelloWorld::runningSchedule));
m_isRunning = false;
Button* button = dynamic_cast<Button*>(m_layout->getChildByTag(UI_BUTTON_START));
button->setTitleText(WStrToUTF8(L"运行"));
}
else
{
//start
this->schedule(schedule_selector(HelloWorld::runningSchedule));
m_isRunning = true;
Button* button = dynamic_cast<Button*>(m_layout->getChildByTag(UI_BUTTON_START));
button->setTitleText(WStrToUTF8(L"暂停"));
}
}
void HelloWorld::runningSchedule(float dt)
{
int speed = dynamic_cast<Slider*>(m_layout->getChildByTag(UI_SLIDER_SPEED))->getPercent();
auto loadingBar = dynamic_cast<LoadingBar*>(m_layout->getChildByTag(UI_LOADINGBAR_LOADING));
int prc = loadingBar->getPercent() + speed / 15;
if(prc > 100)
{
prc = 1;
}
loadingBar->setPercent(prc);
auto numLabel = dynamic_cast<TextAtlas*>(m_layout->getChildByTag(UI_LABELATLAS_LIFENUM));
int num = atoi(numLabel->getStringValue().c_str());
num++;
char buff[100];
sprintf_s(buff,"%d",num);
numLabel->setStringValue(buff);
}
void HelloWorld::menuCloseCallback(Object* pSender)
{
Director::getInstance()->end();
#if (CC_TARGET_PLATFORM == CC_PLATFORM_IOS)
exit(0);
#endif
}
本文介绍如何在Cocos2d-x中实现UI交互,包括按钮点击响应、进度条更新及数值显示等,通过具体示例展示了从CocoStudio编辑界面到代码逻辑的完整流程。
关联程序逻辑与cocoStudio导出文件&spm=1001.2101.3001.5002&articleId=18330863&d=1&t=3&u=4de765e1a8ae4327834db974750f23c7)
5816

被折叠的 条评论
为什么被折叠?



