前端之家收集整理的这篇文章主要介绍了
cocos2dx 点击事件分析(5),
前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。
经过CCEGLViewProtocol的handleTouchesBegin,handleTouchesMove,handleTouchesEnd,handleTouchesCancel处理,
都会CCTouchDispatcher中的下面这些函数,而且都会调用touches,那我们就分析一下touches这个函数
void CCTouchDispatcher::touchesBegan(CCSet *touches,CCEvent *pEvent)
{
if (m_bDispatchEvents)
{
this->touches(touches,pEvent,CCTOUCHBEGAN);
}
}
void CCTouchDispatcher::touchesMoved(CCSet *touches,CCTOUCHMOVED);
}
}
void CCTouchDispatcher::touchesEnded(CCSet *touches,CCTOUCHENDED);
}
}
void CCTouchDispatcher::touchesCancelled(CCSet *touches,CCTOUCHCANCELLED);
}
}
//
// dispatch events 分发触摸事件
//
//CCSet *pTouches 所有触摸点的信息
//*pEvent NULL
//uIndex 触摸类型:CCTOUCHBEGAN,CCTOUCHCANCELLED ....
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
//判断是否需要copy
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
//先处理target触摸事件
if (uTargetedHandlersCount > 0)
{
CCTouch *pTouch;
CCSetIterator setIter;
//因为这里可能同时发过来几个手指的触摸行为,以前分析过CCTOUCHBEGAN和CCTOUCHENDED每次只会传递一个
//多个手指不可能同时按下,总有先后
for (setIter = pTouches->begin(); setIter != pTouches->end(); ++setIter)
{
pTouch = (CCTouch *)(*setIter);
CCTargetedTouchHandler *pHandler = NULL;
CCObject* pObj = NULL;
//遍历所有的TargetedHandler
CCARRAY_FOREACH(m_pTargetedHandlers,pObj)
{
pHandler = (CCTargetedTouchHandler *)(pObj);
if (! pHandler)
{
break;
}
//任何一次触摸事件都是从CCTOUCHBEGAN开始的,如何没有begin那,后面的move,end等等就没有意义
//那么如何表明,你对触摸事件感兴趣呢?就是在ccTouchBegan,即处理begin事件时返回true,那么表明
//控件对这个事件感兴趣,claimed(认领,宣称的意思),如果对begin不感兴趣,那么后面的move,end等就
//不发给你了。
bool bClaimed = false;
if (uIndex == CCTOUCHBEGAN)
{
bClaimed = pHandler->getDelegate()->ccTouchBegan(pTouch,pEvent);
if (bClaimed)
{
pHandler->getClaimedTouches()->addObject(pTouch);
}
} else
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;
}
}
//m_pTargetedHandlers链表的优先级从高到低,而且具有吞噬性,
//即如果一个高优先级控件的处理了一次手指点击的CCTOUCHBEGAN事件,而且,
//这个控件设置了Swallow,那么低优先级的控件都不能处理此时触摸事件
//而且,还会把这次触摸事件从pMutableTouches多点触摸里面移除。
if (bClaimed && pHandler->isSwallowsTouches())
{
if (bNeedsMutableSet)
{
pMutableTouches->removeObject(pTouch);
}
break;
}
}
}
}
//
// process standard handlers 2nd
//标准触摸事件,也是有优先级,但是没有吞噬能力。
//所有的都可以接收
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而没有移除,增加的都加进事件处理链表中。
//
m_bLocked = false;
if (m_bToRemove)
{
m_bToRemove = false;
for (unsigned int i = 0; i < m_pHandlersToRemove->num; ++i)
{
forceRemoveDelegate((CCTouchDelegate*)m_pHandlersToRemove->arr[i]);
}
ccCArrayRemoveAllValues(m_pHandlersToRemove);
}
if (m_bToAdd)
{
m_bToAdd = false;
CCTouchHandler* pHandler = NULL;
CCObject* pObj = NULL;
CCARRAY_FOREACH(m_pHandlersToAdd,pObj)
{
pHandler = (CCTouchHandler*)pObj;
if (! pHandler)
{
break;
}
if (dynamic_cast<CCTargetedTouchHandler*>(pHandler) != NULL)
{
forceAddHandler(pHandler,m_pTargetedHandlers);
}
else
{
forceAddHandler(pHandler,m_pStandardHandlers);
}
}
m_pHandlersToAdd->removeAllObjects();
}
if (m_bToQuit)
{
m_bToQuit = false;
forceRemoveAllDelegates();
}
}