【教程】“回调特性”的使用教程(c++语言)

【新功能】“回调特性”的使用教程:

简介:Cocos Studio2.0.5版本新增回调特性功能。
现在可以直接在编辑器里边指定某个控件的事件的处理函数。
不再需要一个一个去get控件啦。也不再需要因为修改了控件名或者其他属性后,就得去改程序啦。
这些,都可以交给策划了。:878:

ok,以下是正文

创建文件,修改自定义类名称。
点击根节点

在属性栏中修改自定义类类名,如:MyClass

加入UI
控件,
修改回调方法。
选中想要设置回调特性的控件,进入高级属性,修改回调方法和对应回调的名称。
如:Touch方法,名称为onTouch

然后发布资源

在C++
中,创建一个自己的自定义类。
这个类必须遵循如下要求:
a.继承WidgetCallBackHandlerProtocol和 Node(或其他继承自Node的类)
b.重写如下接口:
onLocateTouchCallback
onLocateClickCallback
onLocateEventCallback
返回对Touch、Click、Event三种事件的处理函数。(可以只重写你使用到的回调类型)。
如:
//.h file

#ifndef TestCpp__MyClass
#define TestCpp__MyClass
#include “cocos2d.h”
#include “cocostudio/CocoStudio.h”
#include “cocostudio/WidgetCallBackHandlerProtocol.h”
class MyClass : public cocos2d::Node, public cocostudio::WidgetCallBackHandlerProtocol
{
public:
CREATE_FUNC(MyClass)
MyClass();
virtual cocos2d::ui::Widget::ccWidgetTouchCallback
onLocateTouchCallback(const std::string &callBackName);
virtual cocos2d::ui::Widget::ccWidgetClickCallback
onLocateClickCallback(const std::string &callBackName);
virtual cocos2d::ui::Widget::ccWidgetEventCallback
onLocateEventCallback(const std::string &callBackName);
void onTouch(cocos2d::Ref* sender, cocos2d::ui::Widget::TouchEventType type);
void onClick(cocos2d::Ref* sender);
void onEvent(cocos2d::Ref* sender, int eventType);
private:
std::vectorstd::string _touchTypes;
std::string _click;
std::vectorstd::string _eventTypes;
};
//.cpp file
#include “MyClass.h”

#include “ui/UIText.h”

USING_NS_CC;
using namespace std;
using namespace cocos2d::ui;

MyClass::MyClass()
{}

Widget::ccWidgetTouchCallback MyClass::onLocateTouchCallback(const string &callBackName)
{
if (callBackName == “onTouch”)//判断事件名,返回对应的函数。下同
{
return CC_CALLBACK_2(MyClass::onTouch, this);
}
return nullptr;
}

Widget::ccWidgetClickCallback MyClass::onLocateClickCallback(const string &callBackName)
{
if (callBackName == “onClick”)
{
return CC_CALLBACK_1(MyClass::onClick, this);
}
return nullptr;
}

Widget::ccWidgetEventCallback MyClass::onLocateEventCallback(const string &callBackName)
{
if (callBackName == “onEvent”)
{
return CC_CALLBACK_2(MyClass::onEvent, this);
}
return nullptr;
}

void MyClass::onTouch(cocos2d::Ref* object, cocos2d::ui::Widget::TouchEventType type)
{
CCLOG(“onTouch”);
}

void MyClass::onClick(cocos2d::Ref* sender)
{
CCLOG(“onClick”);
}

void MyClass::onEvent(cocos2d::Ref* sender, int eventType)
{
CCLOG(“onEvent”);
}

为第3
步编写的类创建工厂类
这个类必须继承cocostudio::NodeReader,并重写如下三个接口
getInstance —— 返回工厂类的单例
purge —— 销毁工厂类
createNodeWithFlatBuffers —— 创建第3步编写的类,并调用setPropsWithFlatBuffers
如:
//.h file

#ifndef cocos2d_libs__MyClassReader#define cocos2d_libs__MyClassReader#include “cocos2d.h”#include “cocostudio/CocosStudioExport.h”#include "cocostudio/WidgetReader/NodeReader/NodeReader.h"class MyClassReader : public cocostudio::NodeReader{ public:MyClassReader() {}; ~MyClassReader() {}; static MyClassReader* getInstance();static void purge(); cocos2d::Node* createNodeWithFlatBuffers(const flatbuffers::Table* nodeOptions);};#endif /defined(cocos2d_libs__MyClassReader) /
//.cpp file#include “MyClassReader.h”#include "MyClass.h"USING_NS_CC;static MyClassReader
_instanceMyClassReader = nullptr;MyClassReader
MyClassReader::getInstance(){if (!_instanceMyClassReader) {_instanceMyClassReader = new MyClassReader(); }return _instanceMyClassReader;}void MyClassReader::purge(){CC_SAFE_DELETE(_instanceMyClassReader);}
Node
*
MyClassReader
::
createNodeWithFlatBuffers
(
const

flatbuffers
::
Table
*
nodeOptions
)
{

MyClass
*
node

MyClass
::
create
();

setPropsWithFlatBuffers
(
node
,
nodeOptions
);

return

node
;
}

在加载节点之前注册这个接口到CSLoader

CSLoader* instance = CSLoader::getInstance();instance->registReaderObject(“MyClassReader”,(ObjectFactory::Instance)
MyClassReader::getInstance);注意第一个参数必须是第一步填写的自定义类名加“Reader ”如上述的"MyClassReader"

  1. 使用CreateNode
    加载你的节点。

!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
!!!注意:!!!
你的自定义类的create已经委托给工厂类,只要你注册工厂类的时候没写错,工厂类会在createNode里边create你的自定义类。
所以不需要你自己再create自定义类。最终createNode返回的就是你的自定义类。

#ifndef __TestCpp__MyClass__
#define __TestCpp__MyClass__
#include "cocos2d.h"
#include "cocostudio/CocoStudio.h"
#include "cocostudio/WidgetCallBackHandlerProtocol.h"
class MyClass : public cocos2d::Node, public cocostudio::WidgetCallBackHandlerProtocol
{
public:
      CREATE_FUNC(MyClass)
MyClass();
virtual cocos2d::ui::Widget::ccWidgetTouchCallback onLocateTouchCallback(const std::string &callBackName);
virtual cocos2d::ui::Widget::ccWidgetClickCallback onLocateClickCallback(const std::string &callBackName);
        virtual cocos2d::ui::Widget::ccWidgetEventCallback onLocateEventCallback(const std::string &callBackName);
        void onTouch(cocos2d::Ref* sender, cocos2d::ui::Widget::TouchEventType type);
        void onClick(cocos2d::Ref* sender);
        void onEvent(cocos2d::Ref* sender, int eventType);
private:
std::vector _touchTypes;
std::string _click;
std::vector _eventTypes;
};
//.cpp file
#include "MyClass.h"


#include "ui/UIText.h"


USING_NS_CC;
using namespace std;
using namespace cocos2d::ui;


MyClass::MyClass()
{}


Widget::ccWidgetTouchCallback MyClass::onLocateTouchCallback(const string &callBackName)
{
if (callBackName == "onTouch")//判断事件名,返回对应的函数。下同
{
return CC_CALLBACK_2(MyClass::onTouch, this);
}
return nullptr;
}


Widget::ccWidgetClickCallback MyClass::onLocateClickCallback(const string &callBackName)
{
if (callBackName == "onClick")
{
return CC_CALLBACK_1(MyClass::onClick, this);
}
return nullptr;
}


Widget::ccWidgetEventCallback MyClass::onLocateEventCallback(const string &callBackName)
{
if (callBackName == "onEvent")
{
return CC_CALLBACK_2(MyClass::onEvent, this);
}
return nullptr;
}


void MyClass::onTouch(cocos2d::Ref* object, cocos2d::ui::Widget::TouchEventType type)
{
CCLOG("onTouch");
}


void MyClass::onClick(cocos2d::Ref* sender)
{
CCLOG("onClick");
}


void MyClass::onEvent(cocos2d::Ref* sender, int eventType)
{
CCLOG("onEvent");
}

```

自沙~~~有啥问题尽管问哈

支持lua么?:2:

同问,支持lua么

需要自己在C++里边写个类导出给lua用。

这个稍等会支持。

好麻烦。。。:10::10::10::9::9::9:

好麻烦…都不支持LUA

有没有办法可以简化一下流程呀。
理想的操作方式是 “只要在编辑器里写上类名和函数名” 就可以了,而不需要这么多繁琐的操作。

:14:支持。。。。。我也是这么想的。

lua、js下估计可以。。。

脚本支持反射很容易。

C++不支持反射就做不到了

话说 C++ 是可以实现反射的啊,我以前就做过,做的时候参考了一些网上的文章,我给你列一下:

第一篇:铛铛铛铛 来自触控科技的博客,作者http://www.cocoachina.com/bbs/u.php?action=topic&uid=7515是谁不用我多说吧:11:
C++反射机制的实现
Published on 2012 年 2 月 28 日, by Eddy in C/C++, iOS技术.
http://blog.chukong-inc.com/index.php/2012/02/28/c反射机制的实现

C++反射类和成员函数的实现
http://blog.csdn.net/ihc523/article/details/24143655

c++成员变量反射
http://www.cppblog.com/0xfff/archive/2012/04/25/172716.html

是可以,把所有函数都想办法注册出来。
但是涉及到的改动就太大了。
而且性能上也有不少损失。如果你们愿意这样写,那还真不如直接用lua
(个人之见)

:6::6::6::6::6::6::6::6::6::6::6::6::6::6::6::6::6::6::6::6::6::6::6:

这种用户触发的事件,性能根本就不能来当理由吧……
其实开发者真正关心的是回调部分,其他的都应该帮他们封装好才对。最简单的方案是直接触发消息,开发者代码里面只要自己加Listener就好了。

强烈建议把事件名称(字符串) 作为 Widget的一个公共属性,脚本语言可以通过这个属性去做绑定。

写一个lua类就可以了,不需要先写C++类再导出lua,今天稍后给大家一个lua版本的教程,谢谢支持

我说的是C++支持反射这种事,真不如直接用lua.
如果你们愿意要职业吐槽的做法,那也没问题。把教程里的两个类改改,再提供个宏就行。
不过那并不是反射。(我所认同的反射是不需要改语法的。)

希望版主出个控件类绑定的教程 都不知道怎么用

— Begin quote from ____

引用第15楼lion于2014-12-10 10:36发表的 :
写一个lua类就可以了,不需要先写C++类再导出lua,今天稍后给大家一个lua版本的教程,谢谢支持 http://www.cocoachina.com/bbs/job.php?action=topost&tid=274210&pid=1194600

— End quote

赞。。。在哪呢

和cocosbuilder比起来略显反动啊