cocos2d-x-3.1 事件分发机制 (coco2d-x 学习笔记七)
触摸事件
Sprite* sp1 = Sprite::create("Images/t1.png"); sp1->setPosition(Vec2(visibleSize.width / 2, visibleSize.height / 2)); addChild(sp1, 10,1); auto mTouchListener = EventListenerTouchOneByOne::create(); //单点触摸事件 mTouchListener->setSwallowTouches(true); //true向下传递 mTouchListener->onTouchBegan = [](Touch* touch, Event* event){ //匿名方式设置事件 Sprite* target = static_cast<Sprite*>(event->getCurrentTarget()); Point locationInNode = target->convertToNodeSpace(touch->getLocation()); Size s = target->getContentSize(); Rect normal = Rect(0, 0, s.width, s.height); if (normal.containsPoint(locationInNode)){ log("x=%f,y=%f", locationInNode.x, locationInNode.y); target->setOpacity(0x7F); //设置透明度 return true; //向下传递事件 } return false; }; //绑定方式设置事件 其onTouchBegan函数的内容和匿名方式内容一样 //listener1->onTouchBegan = CC_CALLBACK_2(HelloWorld::onTouchBegan, this); mTouchListener->onTouchMoved = [](Touch* touch, Event* event){}; //触摸移动监听 mTouchListener->onTouchEnded = [](Touch* touch, Event* event){}; //触摸监听结束 /* _eventDispatcher是Node的属性,通过它管理当前节点(场景、层、精灵等)的全部事件的分发。 但它本身是一个单例模式值的引用,在Node的构造函数中, 通过Director::getInstance()->getEventDispatcher(); 获取,有了这个属性,就能方便的处理事件。 */ //将触摸事件交给事件分发器管理 _eventDispatcher->addEventListenerWithSceneGraphPriority(mTouchListener, sp1); /*ps:当再次使用 mTouchListener 的时候,须要使用clone()方法创建一个新的克隆。由于在使用addEventListenerWithSceneGraphPriority方法时,会对当前使用的事件监听器加入�一个已注冊的标记,这使得它不可以被加入�多次。另外,有一点很重要mTouchListener是跟Node绑定的,在Node的析构函数中会被移除。 */
键盘响应事件
auto mKeyboardListener = EventListenerKeyboard::create(); //键盘响应事件 //键盘按下事件监听 mKeyboardListener->onKeyPressed = [](EventKeyboard::KeyCode keyCode, Event* event){ log("keyCode=%d", keyCode); }; //键盘释放事件监听 mKeyboardListener->onKeyReleased = [](EventKeyboard::KeyCode keyCode, Event* event){ log("keyCode=%d", keyCode); if (EventKeyboard::KeyCode::KEY_ESCAPE == keyCode){ #if (CC_TARGET_PLATFORM == CC_PLATFORM_WP8) || (CC_TARGET_PLATFORM == CC_PLATFORM_WINRT) MessageBox("You pressed the close button. Windows Store Apps do not implement a close button.", "Alert"); return; #endif Director::getInstance()->end(); #if (CC_TARGET_PLATFORM == CC_PLATFORM_IOS) exit(0); #endif } }; _eventDispatcher->addEventListenerWithSceneGraphPriority(mKeyboardListener, this); //将键盘响应事件交给分发器来管理
鼠标响应事件
auto _mouseListener = EventListenerMouse::create(); // 事件响应逻辑 _mouseListener->onMouseMove = [=](Event *event){ EventMouse* e = (EventMouse*)event; log("Key=%d", e->getMouseButton()); }; _mouseListener->onMouseUp = [=](Event *event){}; _mouseListener->onMouseDown = [=](Event *event){}; _mouseListener->onMouseScroll = [=](Event *event){}; // 加入�到事件分发器 _eventDispatcher->addEventListenerWithSceneGraphPriority(_mouseListener, this);
自己定义事件
auto mCustomListener = EventListenerCustom::create("my_custom_l", [](EventCustom* event){ char* c = static_cast<char*>(event->getUserData()); log("%s", c); }); /* 将自自己定义事件交给分发器来管理,这样的方式是使用优先级别来设置 SceneGraphPriority和FixedPriority差别在于前者是在析构函数中会被移除 后者是须要手动移除 */_eventDispatcher->addEventListenerWithFixedPriority(mCustomListener, 1); EventCustom _event("my_custom_l"); //char* cstr = "this is my custom listener!"; static int count = 0; ++count; char* buf; sprintf(buf, "this is my custom %d", count); _event.setUserData(buf); _eventDispatcher->dispatchEvent(&_event); //手动触发自己定义事件
加速计事件
//启动加速硬件设备 Device::setAccelerometerEnabled(true); auto mAcListener = EventListenerAcceleration::create([](Acceleration* acc, Event* event){ #define FIX_POS(_pos, _min, _max) \ if (_pos < _min) \ _pos = _min; \ else if (_pos > _max) \ _pos = _max; \ //log("x=%lf,y=%lf", acc->x, acc->y); auto ballSize = sp1->getContentSize(); auto ptNow = sp1->getPosition(); ptNow.x += acc->x * 9.81f; ptNow.y += acc->y * 9.81f; FIX_POS(ptNow.x, (VisibleRect::left().x + ballSize.width / 2.0), (VisibleRect::right().x - ballSize.width / 2.0)); FIX_POS(ptNow.y, (VisibleRect::bottom().y + ballSize.height / 2.0), (VisibleRect::top().y - ballSize.height / 2.0)); sp1->setPosition(ptNow); }); _eventDispatcher->addEventListenerWithSceneGraphPriority(mAcListener, this);