cocos2dx 3.1 触摸机制

在cocos2dx 3.0版本中,废弃了以往2.x版本的写法,咱们先来看一下Layer.h中的一段代码 node

[cpp]   view plain copy 在CODE上查看代码片 派生到个人代码片
  1. /* Callback function should not be deprecated, it will generate lots of warnings. 
  2.     Since 'setTouchEnabled' was deprecated, it will make warnings if developer overrides onTouchXXX and invokes setTouchEnabled(true) instead of using EventDispatcher::addEventListenerWithXXX. 
  3.     */  
  4.     //单点触摸  
  5.     virtual bool onTouchBegan(Touch *touch, Event *unused_event);   
  6.     virtual void onTouchMoved(Touch *touch, Event *unused_event);   
  7.     virtual void onTouchEnded(Touch *touch, Event *unused_event);   
  8.     virtual void onTouchCancelled(Touch *touch, Event *unused_event);  
  9.     //多点触摸  
  10.     virtual void onTouchesBegan(const std::vector<Touch*>& touches, Event *unused_event);  
  11.     virtual void onTouchesMoved(const std::vector<Touch*>& touches, Event *unused_event);  
  12.     virtual void onTouchesEnded(const std::vector<Touch*>& touches, Event *unused_event);  
  13.     virtual void onTouchesCancelled(const std::vector<Touch*>&touches, Event *unused_event);  

 

单点触摸:(即只有注册的Layer才能接收触摸事件) ide

 onTouchBegan:若是返回true:本层的后续Touch事件能够被触发,并阻挡向后层传递 函数

                                 若是返回false,本层的后续Touch事件不能被触发,并向后传递 this

简单点来讲,若是 spa

1.Layer 只有一层的状况: code

virtual bool onTouchBegan(CCTouch *pTouch, CCEvent *pEvent);
a.返回false,则ccTouchMoved(),ccTouchEnded()不会再接收到消息
b.返回true,则ccTouchMoved(),ccTouchEnded()能够接收到消息
2.Layer 有多层的状况:
virtual bool onTouchBegan(CCTouch *pTouch, CCEvent *pEvent);
a.返回false,则本层的onTouchMoved(),onTouchEnded()不会再接收到消息,可是本层之下的其它层会接收到消息
b.返回true,则本层的onTouchMoved(),onTouchEnded()能够接收到消息,可是本层之下的其它层不能再接收到消息

单点触摸简单用法: 事件

在Layer中添加以下代码,重写onTouchxxx函数 rem

[cpp]   view plain copy 在CODE上查看代码片 派生到个人代码片
  1.        auto dispatcher = Director::getInstance()->getEventDispatcher();  
  2. auto listener = EventListenerTouchOneByOne::create();  
  3. listener->onTouchBegan = CC_CALLBACK_2(GameLayer::onTouchBegan,this);  
  4. listener->onTouchMoved = CC_CALLBACK_2(GameLayer::onTouchMoved,this);  
  5. listener->onTouchEnded = CC_CALLBACK_2(GameLayer::onTouchEnded,this);  
  6. listener->setSwallowTouches(true);//不向下传递触摸  
  7. dispatcher->addEventListenerWithSceneGraphPriority(listener,this);  


 listener->setSwallowTouches(true),不向下触摸,简单点来讲,好比有两个sprite ,A 和 B,A在上B在下(位置重叠),触摸A的时候,B不会受到影响 get

  listener->setSwallowTouches(false)反之,向下传递触摸,触摸A也等于触摸了B


多点触摸点单用法(多个Layer获取屏幕事件):
it

[cpp]   view plain copy 在CODE上查看代码片 派生到个人代码片
  1.        auto dispatcher = Director::getInstance()->getEventDispatcher();  
  2. auto listener1 = EventListenerTouchAllAtOnce::create();  
  3. listener1->onTouchesBegan = CC_CALLBACK_2(GameLayer::onTouchesBegan,this);  
  4. listener1->onTouchesMoved = CC_CALLBACK_2(GameLayer::onTouchesMoved,this);  
  5. listener1->onTouchesEnded = CC_CALLBACK_2(GameLayer::onTouchesEnded,this);  
  6. dispatcher->addEventListenerWithSceneGraphPriority(listener1,this);  

或者setTouchEnabled(true),而后重写layer的onTouchsxxx函数


关于eventDispatcher:

  • 获取方法:

  • [cpp]   view plain copy 在CODE上查看代码片 派生到个人代码片
    1. auto dispatcher = Director::getInstance()->getEventDispatcher();  

事件监听器包含如下几种:

  • 触摸事件 (EventListenerTouch)
  • 键盘响应事件 (EventListenerKeyboard)
  • 加速记录事件 (EventListenerAcceleration)
  • 鼠标响应事件 (EventListenerMouse)
  • 自定义事件 (EventListenerCustom)

    以上事件监听器统一由 _eventDispatcher 来进行管理。


优先权:
1.优先级越低,越先响应事件
2.若是优先级相同,则上层的(z轴)先接收触摸事件

有两种方式将 事件监听器 listener1 添加到 事件调度器_eventDispatcher 中:

[cpp]   view plain copy 在CODE上查看代码片 派生到个人代码片
  1. void EventDispatcher::addEventListenerWithSceneGraphPriority(EventListener* listener, Node* node)  
  2.     void EventDispatcher::addEventListenerWithFixedPriority(EventListener* listener, int fixedPriority)  

代码展开一下:
[cpp]   view plain copy 在CODE上查看代码片 派生到个人代码片
  1. void EventDispatcher::addEventListenerWithSceneGraphPriority(EventListener* listener, Node* node)  
  2. {  
  3.     CCASSERT(listener && node, "Invalid parameters.");  
  4.     CCASSERT(!listener->isRegistered(), "The listener has been registered.");  
  5.       
  6.     if (!listener->checkAvailable())  
  7.         return;  
  8.       
  9.     listener->setSceneGraphPriority(node);  
  10.     listener->setFixedPriority(0);  
  11.     listener->setRegistered(true);  
  12.       
  13.     addEventListener(listener);  
  14. }  

[cpp]   view plain copy 在CODE上查看代码片 派生到个人代码片
  1. void EventDispatcher::addEventListenerWithFixedPriority(EventListener* listener, int fixedPriority)  
  2. {  
  3.     CCASSERT(listener, "Invalid parameters.");  
  4.     CCASSERT(!listener->isRegistered(), "The listener has been registered.");  
  5.     CCASSERT(fixedPriority != 0, "0 priority is forbidden for fixed priority since it's used for scene graph based priority.");  
  6.       
  7.     if (!listener->checkAvailable())  
  8.         return;  
  9.       
  10.     listener->setSceneGraphPriority(nullptr);  
  11.     listener->setFixedPriority(fixedPriority);  
  12.     listener->setRegistered(true);  
  13.     listener->setPaused(false);  
  14.   
  15.     addEventListener(listener);  
  16. }  


(1)addEventListenerWithSceneGraphPriority 的事件监听器优先级是0, 并且在 addEventListenerWithFixedPriority 中的事件监听器的优先级不能够设置为 0,由于这个是保留给 SceneGraphPriority 使用的。

(2)另外,有一点很是重要,FixedPriority listener添加完以后须要手动remove,而SceneGraphPriority listener是跟node绑定的,在node的析构函数中会被移除。

移除方法:
[cpp]   view plain copy 在CODE上查看代码片 派生到个人代码片
  1. dispatcher->removeEventListener(listener);  
相关文章
相关标签/搜索