Cocos2d-x 3.0开发(五)关联程序逻辑与cocoStudio导出文件

本篇博客出自阿修罗道,转载请注明出处:http://blog.csdn.net/fansongy/article/details/12795299

1、概述

    上篇说到将CocoStudio的导出文件在程序中运行出来,但是并没有用户交互,即点击响应,程序的逻辑判断也都没有。这篇中我们把它们加进去,这样就可以算一个完整的程序了。先上个图:

Cocos2d-x 3.0开发(五)关联程序逻辑与cocoStudio导出文件_第1张图片

运行后,点击开始,进度条,数字增加,通过slider可以调整进度条增长的速度。

2、界面编辑

    大部分界面编辑都在CocoStudio中完成,怎么编辑可以参照: 

Cocos2d-x 3.0 开发(四)使用CocoStudio创建UI并载入到程序中 

    现在我们要做的工作是将所需要交互控件的Tag记下来,这样我们可以通过Tag找到这个控件。

Cocos2d-x 3.0开发(五)关联程序逻辑与cocoStudio导出文件_第2张图片

将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、本人对项目的总结

 
开发环境: windows  cocos2d-x 3.0 beta cocostudio1.2
     由于 cocos2d-x 3.0 beta 版本相应上一版本有很大的改动。
     所以对示例中的代码做了修改与源博客中的代码不一至,此适应于cocos2d-x 3.0 beta版本。
 下面相应代码供大家参考:
HelloWorldScene.h
#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__


HelloWorldScene.cpp

#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 3.0开发(五)关联程序逻辑与cocoStudio导出文件)