Cocos2dx之touch事件.docx
《Cocos2dx之touch事件.docx》由会员分享,可在线阅读,更多相关《Cocos2dx之touch事件.docx(12页珍藏版)》请在冰豆网上搜索。
Cocos2dx之touch事件
Cocos2dx之touch事件
今天看了下ccocos2dxtouch事件部分的源码,从CCTouch、CCTouchHandler和CCTouchDispatcher简单的做了分析和总结,先直接看源码吧!
1、CCTouch
classCC_DLLCCTouch:
publicCCObject
{
public:
CCTouch()
:
m_nId(0),
m_startPointCaptured(false)
{}
/**returnsthecurrenttouchlocationinOpenGLcoordinates*/
CCPointgetLocation()const;//获取当前touch位置,该位置基于OpenGL坐标
/**returnstheprevioustouchlocationinOpenGLcoordinates*/
CCPointgetPreviousLocation()const;//获取前一次touch位置,该位置基于OpenGL坐标
/**returnsthestarttouchlocationinOpenGLcoordinates*/
CCPointgetStartLocation()const;//获取该touch的起始位置,该位置基于OpenGL坐标
/**returnsthedeltaof2currenttoucheslocationsinscreencoordinates*/
CCPointgetDelta()const;//获取前后两次位置的偏移量,基于OpenGL坐标
/**returnsthecurrenttouchlocationinscreencoordinates*/
CCPointgetLocationInView()const;//当前touch位置,该位置基于屏幕坐标位置
/**returnstheprevioustouchlocationinscreencoordinates*/
CCPointgetPreviousLocationInView()const;//获取touch前一次的位置,基于屏幕坐标位置
/**returnsthestarttouchlocationinscreencoordinates*/
CCPointgetStartLocationInView()const;//获取touch起始位置,基于屏幕坐标位置
voidsetTouchInfo(intid,floatx,floaty)
{
m_nId=id;
m_prevPoint=m_point;
m_point.x=x;
m_point.y=y;
if(!
m_startPointCaptured)
{
m_startPoint=m_point;
m_startPointCaptured=true;
}
}
intgetID()const
{
returnm_nId;
}
private:
intm_nId;
boolm_startPointCaptured;
CCPointm_startPoint;
CCPointm_point;
CCPointm_prevPoint;
};
CCTouch中有三个主要成员,m_startPoint、m_point、m_prevPoint,这三个点都是基于屏幕坐标。
将这三个点转化为OpenGL坐标可以用CCDirector:
:
sharedDirector()->convertToGL(m_point)函数来转化。
2、CCTouchHandler、CCStandardTouchHandler和CCTargetedTouchHandler
classCC_DLLCCTouchHandler:
publicCCObject
{
public:
virtual~CCTouchHandler(void);
/**delegate*/
CCTouchDelegate*getDelegate();//获取touch代理
voidsetDelegate(CCTouchDelegate*pDelegate);//设置touch代理
/**priority*/
intgetPriority(void);//获取代理优先级
voidsetPriority(intnPriority);//获取代理优先级
/**enabledselectors*/
intgetEnabledSelectors(void);//
voidsetEnalbedSelectors(intnValue);
/**initializesaTouchHandlerwithadelegateandapriority*/
virtualboolinitWithDelegate(CCTouchDelegate*pDelegate,intnPriority);
public:
/**allocatesaTouchHandlerwithadelegateandapriority*///创建一个CCTouchHandler
staticCCTouchHandler*handlerWithDelegate(CCTouchDelegate*pDelegate,intnPriority);
protected:
CCTouchDelegate*m_pDelegate;//touch代理
intm_nPriority;//优先级
intm_nEnabledSelectors;//该成员没看出来有什么作用
};
CCTouchHandler主要将touch代理和优先级封装起来,CCTouchHandler还有两个派生对象:
CCStandardTouchHandler和CCTargetedTouchHandler。
这两个派生类很简单不需多说,简单的贴上代码吧。
classCC_DLLCCStandardTouchHandler:
publicCCTouchHandler
{
public:
/**initializesaTouchHandlerwithadelegateandapriority*/
virtualboolinitWithDelegate(CCTouchDelegate*pDelegate,intnPriority);
public:
/**allocatesaTouchHandlerwithadelegateandapriority*/
staticCCStandardTouchHandler*handlerWithDelegate(CCTouchDelegate*pDelegate,intnPriority);
};
classCC_DLLCCTargetedTouchHandler:
publicCCTouchHandler
{
public:
~CCTargetedTouchHandler(void);
/**whetherornotthetouchesareswallowed*/
boolisSwallowsTouches(void);//是否吞掉CCTouch
voidsetSwallowsTouches(boolbSwallowsTouches);//设置是否吞掉CCTouch
/**MutableSetthatcontainstheclaimedtouches*/
CCSet*getClaimedTouches(void);//获取将要处理的CCTouch的集合
/**initializesaTargetedTouchHandlerwithadelegate,apriorityandwhetherornotitswallowstouchesornot*/
boolinitWithDelegate(CCTouchDelegate*pDelegate,intnPriority,boolbSwallow);
public:
/**allocatesaTargetedTouchHandlerwithadelegate,apriorityandwhetherornotitswallowstouchesornot*/
staticCCTargetedTouchHandler*handlerWithDelegate(CCTouchDelegate*pDelegate,intnPriority,boolbSwallow);
protected:
boolm_bSwallowsTouches;//处理CCTouch后是否吞掉该CCTouch
CCSet*m_pClaimedTouches;//要处理的CCTouch集合
};
3、CCTouch事件分发器CCTouchDispatcher
classCC_DLLCCTouchDispatcher:
publicCCObject,publicEGLTouchDelegate
{
public:
~CCTouchDispatcher();
boolinit(void);
CCTouchDispatcher()
:
m_pTargetedHandlers(NULL)
m_pStandardHandlers(NULL)
m_pHandlersToAdd(NULL)
m_pHandlersToRemove(NULL)
{}
public:
/**Whetherornottheeventsaregoingtobedispatched.Default:
true*/
boolisDispatchEvents(void);//事件是否要被分发
voidsetDispatchEvents(boolbDispatchEvents);//设置是否分发事件
/**Addsastandardtouchdelegatetothedispatcher'slist.
SeeStandardTouchDelegatedescription.
IMPORTANT:
Thedelegatewillberetained.
*/
voidaddStandardDelegate(CCTouchDelegate*pDelegate,intnPriority);//向标准代理容器添加代理
/**Addsatargetedtouchdelegatetothedispatcher'slist.
SeeTargetedTouchDelegatedescription.
IMPORTANT:
Thedelegatewillberetained.
*/
voidaddTargetedDelegate(CCTouchDelegate*pDelegate,intnPriority,boolbSwallowsTouches);//向目标代理容器添加代理
/**Removesatouchdelegate.
Thedelegatewillbereleased
*/
voidremoveDelegate(CCTouchDelegate*pDelegate);//移除特定代理
/**Removesalltouchdelegates,releasingallthedelegates*/
voidremoveAllDelegates(void);//移除所有代理
/**Changesthepriorityofapreviouslyaddeddelegate.Thelowerthenumber,
thehigherthepriority*/
voidsetPriority(intnPriority,CCTouchDelegate*pDelegate);//设置特定代理的优先级
voidtouches(CCSet*pTouches,CCEvent*pEvent,unsignedintuIndex);//分发事件逻辑处理,主要看的函数
//以下是对四种事件的处理
virtualvoidtouchesBegan(CCSet*touches,CCEvent*pEvent);
virtualvoidtouchesMoved(CCSet*touches,CCEvent*pEvent);
virtualvoidtouchesEnded(CCSet*touches,CCEvent*pEvent);
virtualvoidtouchesCancelled(CCSet*touches,CCEvent*pEvent);
public:
CCTouchHandler*findHandler(CCTouchDelegate*pDelegate);//根据代理查找特定CCTouchHandler
protected:
voidforceRemoveDelegate(CCTouchDelegate*pDelegate);
voidforceAddHandler(CCTouchHandler*pHandler,CCArray*pArray);
voidforceRemoveAllDelegates(void);
voidrearrangeHandlers(CCArray*pArray);//重新根据优先级对代理排序
CCTouchHandler*findHandler(CCArray*pArray,CCTouchDelegate*pDelegate);
protected:
CCArray*m_pTargetedHandlers;//目标事件代理容器
CCArray*m_pStandardHandlers;//标准事件代理容器
boolm_bLocked;//是否被锁
boolm_bToAdd;//是否需要添加
boolm_bToRemove;//是否需要删除
CCArray*m_pHandlersToAdd;//要添加的代理容器
struct_ccCArray*m_pHandlersToRemove;//要删除的代理容器
boolm_bToQuit;//是否要退出
boolm_bDispatchEvents;//是否要处理touch事件
//4,1foreachtypeofevent
structccTouchHandlerHelperDatam_sHandlerHelperData[ccTouchMax];
};
我们主要看一看voidtouches(CCSet*pTouches,CCEvent*pEvent,unsignedintuIndex);这个函数看看touch事件分发器是如何实现事件的分发。
先贴上该函数源码
voidCCTouchDispatcher:
:
touches(CCSet*pTouches,CCEvent*pEvent,unsignedintuIndex)
{
CCAssert(uIndex>=0&&uIndex<4,"");//检查4种touch事件的类型
CCSet*pMutableTouches;
m_bLocked=true;//正在进行事件分发的时候先锁定,避免代理容器内部发生变化
//optimizationtopreventamutablecopywhenitisnotnecessary
unsignedintuTargetedHandlersCount=m_pTargetedHandlers->count();//获取目标事件代理个数
unsignedintuStandardHandlersCount=m_pStandardHandlers->count();//获取标准事件代理个数
boolbNeedsMutableSet=(uTargetedHandlersCount&&uStandardHandlersCount);//需不需要拷贝CCTouch容器
pMutableTouches=(bNeedsMutableSet?
pTouches->mutableCopy():
pTouches);//拷贝CCTouch容器用于向标准touch代理分发事件
structccTouchHandlerHelperDatasHelper=m_sHandlerHelperData[uIndex];
//
//processthetargethandlers1st
//
if(uTargetedHandlersCount>0)
{
CCTouch*pTouch;
CCSetIteratorsetIter;
for(setIter=pTouches->begin();setIter!
=pTouches->end();++setIter)//遍历CCTouch集合
{
pTouch=(CCTouch*)(*setIter);
CCTargetedTouchHandler*pHandler=NULL;
CCObject*pObj=NULL;
CCARRAY_FOREACH(m_pTargetedHandlers,pObj)//对于每一个CCTouch,遍历每一个目标事件代理处理器
{
pHandler=(CCTargetedTouchHandler*)(pObj);
if(!
pHandler)
{
break;
}
boolbClaimed=false;//是否要得到处理
if(uIndex==CCTOUCHBEGAN)
{
bClaimed=pHandler->getDelegate()->ccTouchBegan(pTouch,pEvent);//调用代理的ccTouchBegan函数
if(bClaimed)//如果ccTouchBegan函数返回true,说明事件要被处理
{
pHandler->getClaimedTouches()->addObject(pTouch);//将该touch事件加入到该touch事件处理器的待处理事件容器中
}
}else
if(pHandler->getClaimedTouches()->containsObject(pTouch))//判断handler内是否有该CCTouch
{
//movedendedcanceled
bClaimed=true;//标记要被处理
switch(sHelper.m_type)
{
caseCCTOUCHMOVED:
pHandler->getDelegate()->ccTouchMoved(pTouch,pEvent);//注意处理CCTouchMoved不会移除相应CCTouch
break;
caseCCTOUCHENDED:
pHandler->getDelegate()->ccTouchEnded(pTouch,pEvent);
pHandler->getClaimedTouches()->removeObject(pTouch);//从代理handler中的要处理的CCTouch容器中移除该CCTouch
break;
caseCCTOUCHCANCELLED:
pHandler->getDelegate()->ccTouchCancelled(pTouch,pEvent);
pHandler->getClaimedTouches()->removeObject(pTouch);//从代理handler中的要处理的CCTouch容器中移除该CCTouch
break;
}
}
if(bClaimed&&pHandler->isSwallowsTouches())//已经被处理并且要吞掉
{
if(bNeedsMutableSet)//
{
pMutableTouches->removeObject(pTouch);//从用于向标准代理分发事件的容器中移除该CCTouch
}
break;
}
}
}
}
//
//processstandardhandlers2nd
//处理标准事件的分发,比目标事件简单
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)
{
caseCCTOUCHBEGAN:
pHandler->getDelegate()->ccTouchesBegan(pMutableTouches,pEvent);
break;
caseCCTOUCHMOVED:
pHandler->getDelegate()->ccTouchesMoved(pMutableTouches,pEvent);
break;
caseCCTOUCHENDED:
pHandler->getDelegate()->ccTouchesEnded(pMutableTouches,pEvent);
break;
caseCCTOUCHCANCELLED:
pHandler->getDelegate()->ccTouchesCancelled(pMutableTouches,pEvent);
break;
}
}
}
if(bNeedsMutableSet)
{