如何讓自定義Layer觸發觸摸事件?node
bool LayerXXX::init() { this->setTouchEnabled(true); CCTouchDispatcher* td = CCDirector::sharedDirector()->getTouchDispatcher(); td->addTargetedDelegate(this, 0, true); //kCCMenuHandlerPriority - 10 // ... }
CCTouchDispatcher是管理cocos2d-x中全部Touch事件派發的類,ui
CCTouchDispatcher中包含了兩個CCTouchHandler的列表,
分別存儲StandardTouchHandler和 TargetedTouchHandler。
屬性:
this->mTouchPriporty
Layer 優先級越小越高
越低越先響應事件
實驗一:當兩個Layer優先級同等的時候會怎麼樣呢?
實驗發現,同等優先級下,後添加的Layer先響應事件。this
//------------------------------- //Touch1 100 //Touch2 100 Touch1Layer* touch1layer = Touch1Layer::create( ccc4f(255,0,0,128), 100, 100 ); this->addChild( touch1layer ); touch1layer->setPosition(200, 100); Touch2Layer* touch2layer = Touch2Layer::create( ccc4f(255,255,0,128), 100, 100 ); this->addChild( touch2layer ); touch2layer->setPosition(250, 100); //結果: //Touch2 //Touch1 //------------------------------- //Touch1 100 //Touch2 100 Touch2Layer* touch2layer = Touch2Layer::create( ccc4f(255,255,0,128), 100, 100 ); this->addChild( touch2layer ); touch2layer->setPosition(250, 100); Touch1Layer* touch1layer = Touch1Layer::create( ccc4f(255,0,0,128), 100, 100 ); this->addChild( touch1layer ); touch1layer->setPosition(200, 100); 結果: Touch1 Touch2 ------------------------------- Touch1 100 Touch2 99 Touch2Layer* touch2layer = Touch2Layer::create( ccc4f(255,255,0,128), 100, 100 ); this->addChild( touch2layer ); touch2layer->setPosition(250, 100); Touch1Layer* touch1layer = Touch1Layer::create( ccc4f(255,0,0,128), 100, 100 ); this->addChild( touch1layer ); touch1layer->setPosition(200, 100); //結果: //Touch2 //Touch1 //說明優先級越小越先觸發事件 //-------------------------------
如何阻塞事件的向後傳遞?
原理:
mSwallowsTouches = false的時候,該層的touch事件若接受處理後,touch事件穿透,進入下個註冊touch事件的layer進行處理
若mSwallowsTouches = true時,當該層處理touch事件的時候,若bool ccTouchBegan(CCTouch *pTouch, CCEvent *pEvent);
return true時候,則touch事件被該層接收走,其餘優先級較低的,就不會接收到touch事件的處理申請了。
關於ccTouchBegan的返回值
true:
本層的後續Touch事件能夠被觸發,並阻擋向後層傳遞
false:
本層的後續Touch事件不能被觸發,並向後傳遞
總結:spa
如何阻塞事件的向後傳遞?code
主要是利用了TargetedTouchDelegate 的一個叫SwallowTouch的參數 ,若是這個開關打開的話,對象
比他權限低的handler 是收不到 觸摸響應的,這裏的權限低的意思是先看priority(priority越低的優先級越高)再看哪一個Layer最後addChild進去(越後添加的優先級越高)。blog
CCMenu 就是開了Swallow 而且權限爲-128(權限是越小越好),因此CCMenu的事件不會出現擊穿事件
mSwallowsTouches = true 而且 ccTouchBegan 返回 true
如何讓Layer全部觸摸同時穿透Begin、Move、End事件?
mSwallowsTouches = false 而且 ccTouchBegan 返回 true
ccTouchBegan 返回 true 表示同層處理後續事件(吞噬)
ccTouchBegan 返回 false 表示同層不處理後續事件(Move End Cancled) (擊穿)
mSwallowsTouches 設爲 true 表示觸摸不向下層傳遞(不必定 如mSwallowsTouches爲true began返回false仍是會向後傳遞)
mSwallowsTouches 設爲 false 表示觸摸向下層傳遞(不知有啥用)
this->mTouchPriporty 越小,越先接收到觸摸
this->mTouchPriporty 同等,越後addChild的越先響應
如何管理多個對話框的優先級?
事件的優先級和繪圖的優先級的關係和區別?
VertexZ 又是什麼?(VertexZ是openGl的z軸)
繪圖的優先級叫ZOrder
如何改版繪圖的優先級?
如在容器中經過調用
this->reorderChild(CCNode* child, int zOrder);
如何設置觸摸事件的優先級?
CCTouchDispatcher::sharedDispatcher()->setPriority(kCCMenuTouchPriority - 1, layer);
如何獲得觸摸事件的優先級?
this->mTouchPriporty (CCNode類成員 私有變量)
如何遍歷容器獲取特定的對象??ip
void Touch1Layer::setFocus() { // 將zorder=1; priority= kCCMenuTouchPriority - 2; // 設置zorder SceneController::GetInstancePtr()->getCurLayer()->reorderChild(this, 1); // 設置優先級 CCTouchDispatcher::sharedDispatcher()->setPriority(kCCMenuTouchPriority - 2, this); } void Touch1Layer::loseAllFocus() { // 獲取頂層的全部節點 CCArray* arrChilds = SceneController::GetInstancePtr()->getCurLayer()->getChildren(); for(int i=0; i< arrChilds->count(); i++) { CCLayerColor* layer = dynamic_cast< CCLayerColor* >( arrChilds->objectAtIndex(i) ); // 跳過本身(不撤銷本身的優先級) if(layer != NULL && layer != this) { // 將zorder=0; priority= kCCMenuTouchPriority - 1; SceneController::GetInstancePtr()->getCurLayer()->reorderChild(layer, 0); CCTouchDispatcher::sharedDispatcher()->setPriority(kCCMenuTouchPriority - 1, layer); } } }
如何判斷點在矩形內部?
get
CCPoint pos = this->getPosition(); CCSize size = this->getContentSize(); CCRect rect(pos.x, pos.y, size.width, size.height); if( CCRect::CCRectContainsPoint(rect, point) ) { }
z值大的成員在z值小的成員的上面;
官方解釋:
Differences between openGL Z vertex and cocos2d Z order:
- OpenGL Z modifies the Z vertex, and not the Z order in the relation between parent-children
- OpenGL Z might require to set 2D projection
- cocos2d Z order works OK if all the nodes uses the same openGL Z vertex. eg: vertexZ = 0
@warning: Use it at your own risk since it might break the cocos2d parent-children z order