时间:2021-07-01 10:21:17 帮助过:60人阅读
~~~~我的生活,我的点点滴滴!! 在介绍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);