~~~~我的生活,我的点点滴滴!! 在介绍CC_CALLBACK_X功能之前,我们需要学习一下c11 的几个新特性 std::function std::bind,总结了一些,先学习学习 狂点这里 我们假设你已经了解点上面的知识,我们来开始学习cocos2d-x 3.0的回调函数绑定新用法,先由h
~~~~我的生活,我的点点滴滴!!
在介绍CC_CALLBACK_X功能之前,我们需要学习一下c++11 的几个新特性 std::function std::bind,总结了一些,先学习学习 狂点这里
我们假设你已经了解点上面的知识,我们来开始学习cocos2d-x 3.0的回调函数绑定新用法,先由helloWorld里面的关闭按钮引起我们的话题 :
auto closeItem = MenuItemImage::create("0.png", "1.png", CC_CALLBACK_1(HelloWorld::menuCloseCallback, this));
closeItem->setPosition(Point(400,50));
auto menu = Menu::create(closeItem, NULL);
menu->setPosition(Point::ZERO);
this->addChild(menu);// new callbacks based on C++11 #define CC_CALLBACK_0(__selector__,__target__, ...) std::bind(&__selector__,__target__, ##__VA_ARGS__) #define CC_CALLBACK_1(__selector__,__target__, ...) std::bind(&__selector__,__target__, std::placeholders::_1, ##__VA_ARGS__) #define CC_CALLBACK_2(__selector__,__target__, ...) std::bind(&__selector__,__target__, std::placeholders::_1, std::placeholders::_2, ##__VA_ARGS__) #define CC_CALLBACK_3(__selector__,__target__, ...) std::bind(&__selector__,__target__, std::placeholders::_1, std::placeholders::_2, std::placeholders::_3, ##__VA_ARGS__)
我们先粗俗的这样理解一下,如果要绑定的回调函数不带参数 那就使用 CC_CALLBACK_0 如果带有1个就使用CC_CALLBACK_1,依次类推下去,我们看看他怎么和function结合起来用的,看下MenuItemImage::create的声明
/** creates a menu item with a normal and selected image with a callable object */ static MenuItemImage* create(const std::string&normalImage, const std::string&selectedImage, const ccMenuCallback& callback);最后一个参数是回调的声明,我们去看看
typedef std::functionccMenuCallback;
所以最后直白点就是下面代码
std::function我们会疑问,那个事先未绑定的参数是在什么时候传进去的了。我们调试跟踪,在下面这一段代码里面设置进去ccMenuCallback = std::bind(&HelloWorld::menuCloseCallback, this, std::placeholders::_1);
在他的直属父类里面,由触摸结束 onTouchEnded 里调用
void Menu::onTouchEnded(Touch* touch, Event* event)
{
CCASSERT(_state == Menu::State::TRACKING_TOUCH, "[Menu ccTouchEnded] -- invalid state");
this->retain();
if (_selectedItem)
{
_selectedItem->unselected();
_selectedItem->activate();
}
_state = Menu::State::WAITING;
this->release();
} _selectedItem->activate(); 这个activate()为虚函数,他会调用自己的实现void MenuItem::activate()
{
if (_enabled)
{
if( _callback )
{
_callback(this);
}
#if CC_ENABLE_SCRIPT_BINDING
if (kScriptTypeNone != _scriptType)
{
BasicScriptData data(this);
ScriptEvent scriptEvent(kMenuClickedEvent,&data);
ScriptEngineManager::getInstance()->getScriptEngine()->sendEvent(&scriptEvent);
}
#endif
}
}//我们随便添加三个参数,看看对不对,我们在里面只打印输出一下 void menuCloseCallback(cocos2d::Ref* pSender, int a, int b, int c);
auto closeItem = MenuItemImage::create("0.png", "1.png",
std::bind(&HelloWorld::menuCloseCallback, this, std::placeholders::_1, 3, 4, 5));
closeItem->setPosition(Point(400,50));
auto menu = Menu::create(closeItem, NULL);
menu->setPosition(Point::ZERO);
this->addChild(menu);menuClose a = 3, b = 4, c = 5
好了,简简单单的把CC_CALLBACK说完了,以后在补充吧。
接下来讲一下怎么添加一个空白Layer层来实现类似于游戏中“暂停”等功能?
实现起来不难,网上搜搜也有很多方法,其他的方法我这里不说,我只想知道通过添加一个空白层到最上面的方法,下面先看代码:
#include "SwallowTouch.h"
SwallowTouch *SwallowTouch::Create(Color4B &color, float width, float height)
{
SwallowTouch *ret = new SwallowTouch();
if( ret && ret->init(color, width, height) )
{
ret->autorelease();
return ret;
}
CC_SAFE_DELETE(ret);
return nullptr;
}
bool SwallowTouch::init(const Color4B& color, GLfloat width, GLfloat height)
{
if( !LayerColor::initWithColor(color, width, height) )
{
return false;
}
auto listener = EventListenerTouchOneByOne::create();
//设置吞噬Touches
listener->setSwallowTouches(true);
//简单的lambda表达式设置返回值为true,必须返回true,这样才能有效
listener->onTouchBegan = [](Touch* touch, Event* event)
{
return true;
};
_eventDispatcher->addEventListenerWithSceneGraphPriority(listener, this);
return true;
}最后只需要在使用的时候,设置他的zOrder值比当前所有的精灵的zOrder都大就ok了,看下面使用代码:
SwallowTouch *st = SwallowTouch::Create(Color4B(0,0,0,100), 200,300); st->setPosition(Point(visibleSize.width * 0.5, visibleSize.height * 0.5)); //设置一个很大的zOrder this->addChild(st, 10000);