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);  
相關文章
相關標籤/搜索