cocos2dx 不要直接在 onEnter 裡面 addTargetedDelegate (或 addStandardDelegate)

來源:互聯網
上載者:User

原文連結:http://blog.csdn.net/zhangxaochen/article/details/8064010

 今天看別人 cocos2d 代碼的時候發現個怪現象, 整個工程裡面 沒有 setTouchEnabled(true) 這樣的代碼, 但是程式跑起來的時候卻可以響應 觸屏事件。於是下斷點跟蹤啊跟蹤,發現 m_bIsTouchEnabled 這個變數確實是 false。。 那麼這個layer 到底是怎麼響應觸摸事件的呢?
 存在即合理,空穴不來風。經過別人提醒, 意識到原因在這裡:

 virtual void onEnter(){  CCLayer::onEnter();  d->getTouchDispatcher()->addTargetedDelegate(this, 0, false); }

 類內覆寫了 onEnter 函數,並且 addTargetedDelegate , 居然就可以不用 setTouchEnabled 了。 很有意思的樣子, 那麼不得不看一下 setTouchEnabled 是怎麼工作的了。轉到 CCLayer.cpp line:151,看到函數實現:

/// isTouchEnabled settervoid CCLayer::setTouchEnabled(bool enabled){    if (m_bIsTouchEnabled != enabled)    {        m_bIsTouchEnabled = enabled;        if (m_bIsRunning)        {            if (enabled)            {                this->registerWithTouchDispatcher();            }            else            {                // have problems?                CCDirector* pDirector = CCDirector::sharedDirector();                pDirector->getTouchDispatcher()->removeDelegate(this);            }        }    }}

這個setTouchEnabled 函數做兩件事情:
1. 賦值 m_bIsTouchEnabled = enabled
2. if(m_bIsRunning){ if (enabled) this->registerWithTouchDispatcher(); else removeDelegate(this); }
注意: 這裡首先判斷 if( m_bIsRunning),就是說,如果在初始化 函數init 裡面設定 setTouchEnabled(true), 這時候還沒 run起來,所以並不會執行這一段。否則這裡 register一次, onEnter 裡面預設再 register一次程式就會出問題了

那麼 registerWithTouchDispatcher() 幹什麼事情呢?
跳轉到定義可以看到:

void CCLayer::registerWithTouchDispatcher(){    CCDirector* pDirector = CCDirector::sharedDirector();    if (m_pScriptHandlerEntry)    {        if (m_pScriptHandlerEntry->isMultiTouches())        {            pDirector->getTouchDispatcher()->addStandardDelegate(this, 0);            LUALOG("[LUA] Add multi-touches event handler: %d", m_pScriptHandlerEntry->getHandler());        }        else        {            pDirector->getTouchDispatcher()->addTargetedDelegate(this,                                                                       m_pScriptHandlerEntry->getPriority(),                                                                       m_pScriptHandlerEntry->getSwallowsTouches());            LUALOG("[LUA] Add touch event handler: %d", m_pScriptHandlerEntry->getHandler());        }        return;    }    pDirector->getTouchDispatcher()->addStandardDelegate(this,0);}

除去if (m_pScriptHandlerEntry) 那一段不管(似乎是用來控制 script 代碼的行為,我也不大懂), 函數主要做的事情就是一句話:

pDirector->getTouchDispatcher()->addStandardDelegate(this,0);

就是說,預設情況下, CCLayer 註冊的是 standardDelegate。

理順一下, 我們的代碼應該:
1. init 函數裡面設定 setTouchEnabled(true);
2. 類內覆寫函數 registerWithTouchDispatcher, 設定 addStandardDelegate 或者 targetedDelegate,
這樣,當初始化時調用 setTouchEnabled(true) 的時候,首先會設定 m_bIsTouchEnabled 為 true, 由於 m_bIsRunning==false, 這時還不會 registerWithTouchDispatcher。 然後程式run起來, 調用 onEnter 函數的時候,這裡會(見 CCLayer.cpp line:233):

    if (m_bIsTouchEnabled)    {        this->registerWithTouchDispatcher();    }

如果沒有 setTouchEnabled, 沒有覆寫 registerWithTouchDispatcher,而是直接覆寫的 onEnter函數,像本文一開始提到的:

 virtual void onEnter(){  CCLayer::onEnter();  d->getTouchDispatcher()->addTargetedDelegate(this, 0, false); }

會怎樣?會節省代碼嗎?不會。因為 m_bIsTouchEnabled==false, 所以 onExit 的時候, CCLayer::onExit() 並不會 removeDelegate, 所以我們還需要手動再覆寫 onExit 函數,像這樣:

void TestLayer::onExit(){    CCDirector::sharedDirector()->getTouchDispatcher()->removeDelegate(this);    CCLayer::onExit();}

同時, 因為 m_bIsTouchEnabled==false, 當你注意到這裡的時候你總會陷入邏輯混亂: 沒有 enable touch 這個類居然也可以響應觸摸!! 就像我看人家代碼一樣鬱悶。什麼JB事嘛。。

原文連結:http://blog.csdn.net/zhangxaochen/article/details/8064010

{{OVER}}

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.