最近项目中用到了cocos2dx来开发一个基于陀螺仪的demo,忙了半个星期,一边学习一边开发,总算搞了出来。这里备份下开发中学习到的一些cocos2dx知识。
CONTENTS
cocos2dx事件响应源码摘录:
基于版本:2.2.1,代码版权属于cocos原作者。
CCLayer关于事件响应的代码:
setTouchEnabled:
void CCLayer::setTouchEnabled(bool enabled) { if (m_bTouchEnabled != enabled) { m_bTouchEnabled = enabled; if (m_bRunning) { if (enabled) {//注册事件响应 this->registerWithTouchDispatcher(); } else {//去除注册事件响应 // have problems? CCDirector::sharedDirector()->getTouchDispatcher()->removeDelegate(this); } } } }
registerWithTouchDispatcher:
void CCLayer::registerWithTouchDispatcher() { CCTouchDispatcher* pDispatcher = CCDirector::sharedDirector()->getTouchDispatcher(); // Using LuaBindings if (m_pScriptTouchHandlerEntry) {//lua相关,先略去 。。。。。 } else { //从此处可以发现,TouchMode和TouchPriority可以决定注册事件响应的类型。 //而Mode和Priority可以通过get/set设置。 if( m_eTouchMode == kCCTouchesAllAtOnce ) { pDispatcher->addStandardDelegate(this, 0); } else { pDispatcher->addTargetedDelegate(this, m_nTouchPriority, true); } } } //TouchMode的枚举定义如下: typedef enum { kCCTouchesAllAtOnce, kCCTouchesOneByOne, } ccTouchesMode; //get set 如下: void CCLayer::setTouchMode(ccTouchesMode mode) { if(m_eTouchMode != mode) { m_eTouchMode = mode; if( m_bTouchEnabled) { setTouchEnabled(false); setTouchEnabled(true); } } } void CCLayer::setTouchPriority(int priority) { if (m_nTouchPriority != priority) { m_nTouchPriority = priority; if( m_bTouchEnabled) { setTouchEnabled(false); setTouchEnabled(true); } } } int CCLayer::getTouchPriority() { return m_nTouchPriority; } int CCLayer::getTouchMode() { return m_eTouchMode; }
代码看到此处,根据前文【 cocos2dx学习笔记:吞噬事件相应 】提到的方法,也可以使用下面代码:
//CCDirector::sharedDirector()->getTouchDispatcher()->addTargetedDelegate(this, -210, true); this->setTouchPriority(-210); this->setTouchMode(kCCTouchesOneByOne); this->setTouchEnabled(true);
CCTouchDispatcher:
void CCTouchDispatcher::touches(CCSet *pTouches, CCEvent *pEvent, unsigned int uIndex) { CCAssert(uIndex >= 0 && uIndex < 4, ""); CCSet *pMutableTouches; m_bLocked = true; // optimization to prevent a mutable copy when it is not necessary unsigned int uTargetedHandlersCount = m_pTargetedHandlers->count(); unsigned int uStandardHandlersCount = m_pStandardHandlers->count(); bool bNeedsMutableSet = (uTargetedHandlersCount && uStandardHandlersCount); pMutableTouches = (bNeedsMutableSet ? pTouches->mutableCopy() : pTouches); struct ccTouchHandlerHelperData sHelper = m_sHandlerHelperData[uIndex]; // // process the target handlers 1st // if (uTargetedHandlersCount > 0) { CCTouch *pTouch; CCSetIterator setIter; for (setIter = pTouches->begin(); setIter != pTouches->end(); ++setIter) { pTouch = (CCTouch *)(*setIter); CCTargetedTouchHandler *pHandler = NULL; CCObject* pObj = NULL; CCARRAY_FOREACH(m_pTargetedHandlers, pObj) { pHandler = (CCTargetedTouchHandler *)(pObj); if (! pHandler) { break; } bool bClaimed = false; if (uIndex == CCTOUCHBEGAN) { bClaimed = pHandler->getDelegate()->ccTouchBegan(pTouch, pEvent); //如果该触摸began返回true,说明handler开始处理这个事件(,但是不代表handler要吞噬这个事件!!!) if (bClaimed) { pHandler->getClaimedTouches()->addObject(pTouch); } } else //经过测试发现,当一个触摸事件生成之后,从began,到end和cancel,都是同一个对象。 if (pHandler->getClaimedTouches()->containsObject(pTouch)) { // moved ended canceled bClaimed = true; switch (sHelper.m_type) { case CCTOUCHMOVED: pHandler->getDelegate()->ccTouchMoved(pTouch, pEvent); break; case CCTOUCHENDED: pHandler->getDelegate()->ccTouchEnded(pTouch, pEvent); pHandler->getClaimedTouches()->removeObject(pTouch); break; case CCTOUCHCANCELLED: pHandler->getDelegate()->ccTouchCancelled(pTouch, pEvent); pHandler->getClaimedTouches()->removeObject(pTouch); break; } } if (bClaimed && pHandler->isSwallowsTouches()) { if (bNeedsMutableSet) { pMutableTouches->removeObject(pTouch); } //注意这里的break,如果目标触摸被响应而且被设置吞噬,那么直接跳出内层循环,后续handler均不能响应这个触摸。 break; } } } } // // process standard handlers 2nd // //当目标触摸全部结束之后,将挑剩下的touch事件一次性丢给标准触摸相应。 if (uStandardHandlersCount > 0 && pMutableTouches->count() > 0) { CCStandardTouchHandler *pHandler = NULL; CCObject* pObj = NULL; CCARRAY_FOREACH(m_pStandardHandlers, pObj) { pHandler = (CCStandardTouchHandler*)(pObj); if (! pHandler) { break; } switch (sHelper.m_type) { case CCTOUCHBEGAN: pHandler->getDelegate()->ccTouchesBegan(pMutableTouches, pEvent); break; case CCTOUCHMOVED: pHandler->getDelegate()->ccTouchesMoved(pMutableTouches, pEvent); break; case CCTOUCHENDED: pHandler->getDelegate()->ccTouchesEnded(pMutableTouches, pEvent); break; case CCTOUCHCANCELLED: pHandler->getDelegate()->ccTouchesCancelled(pMutableTouches, pEvent); break; } } } if (bNeedsMutableSet) { pMutableTouches->release(); } // // Optimization. To prevent a [handlers copy] which is expensive // the add/removes/quit is done after the iterations // m_bLocked = false; 。。。。。。 。。。。。。 }
发表评论