Cocos2d-X 学习笔记 22 CCLayer 界面Touch事件处理

Cocos2d 开发中提供了两种touch处理方式,Standard Touch Delegate和 Targeted Touch Delegate方式(参见CCTouchDelegateProtocol.h中源代码),cclayer认是采用第一种方式(参见cclayer的 registerWithTouchdispatcher方法)。在源码中可以看见cclayer继承了CCTouchDelegate


class CC_DLL cclayer : public CCNode,public CCTouchDelegate,public CCAccelerometerDelegate,public CCKeypadDelegate

cclayer中有一个cctouchesMode 变量用来管理是单点触摸还是多点触摸。cctouchesMode的定义如下:

typedef enum {
kCCtouchesAllAtOnce,
kCCtouchesOneByOne,
} cctouchesMode;

其中kCCtouchesAllAtOnce表示单点触摸,也就是cocos2dx认的,kCCtouchesOneByOne表示多点触摸。在cclayer.cpp源码文件的构造函数中我们可以看见认设置:

cclayer::cclayer()
: m_bTouchEnabled(false)
,m_bAccelerometerEnabled(false)
,m_bKeypadEnabled(false)
,m_pScriptTouchHandlerEntry(NULL)
,m_pScriptKeypadHandlerEntry(NULL)
,m_pScriptAccelerateHandlerEntry(NULL)
,m_nTouchPriority(0)
,m_etouchMode(kCCtouchesAllAtOnce)
{
m_bIgnoreAnchorPointForPosition = true;
setAnchorPoint(ccp(0.5f,0.5f));
}

在源码cclayer中就有函数setTouchMode用来设置两种模式:

void cclayer::setTouchMode(cctouchesMode mode)
{
if(m_etouchMode != mode)
{
m_etouchMode = mode;

if( m_bTouchEnabled)
{
setTouchEnabled(false);
setTouchEnabled(true);
}
}
}


所以,我们在继承的cclayer类中,只需要调用函数就可以改变单点还是多点触摸。在源码的cclayer中还有一个变量用来控制是否可以响应用户的触摸变量m_bTouchEnabled。要响应触摸还得设置m_bTouchEnabled为true。对应也有一个设置函数

/// isTouchEnabled setter
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函数

/// Touch and Accelerometer related


void cclayer::registerWithTouchdispatcher()
{
CCTouchdispatcher* pdispatcher = CCDirector::sharedDirector()->getTouchdispatcher();


// Using LuaBindings
if (m_pScriptTouchHandlerEntry)
{
if (m_pScriptTouchHandlerEntry->isMultitouches())
{
pdispatcher->addStandardDelegate(this,0);
LUALOG("[LUA] Add multi-touches event handler: %d",m_pScriptTouchHandlerEntry->getHandler());
}
else
{
pdispatcher->addTargetedDelegate(this,
m_pScriptTouchHandlerEntry->getPriority(),
m_pScriptTouchHandlerEntry->getSwallowstouches());
LUALOG("[LUA] Add touch event handler: %d",m_pScriptTouchHandlerEntry->getHandler());
}
}
else
{
if( m_etouchMode == kCCtouchesAllAtOnce ) {
pdispatcher->addStandardDelegate(this,0);
} else {
pdispatcher->addTargetedDelegate(this,m_nTouchPriority,true);
}
}
}


可知,根据m_etouchMode 的类型调用的CCDirector的CCTouchdispatcher变量来注册通知


所以我们有两种方法可以再自己的cclayer中来响应触摸。

方法1:

setTouchMode(kCCtouchesAllAtOnce);//单点触摸
setTouchEnabled(true);

setTouchMode(kCCtouchesOneByOne);//多点触摸
setTouchEnabled(true);

方法二:

CCDirector::sharedDirector()->getTouchdispatcher()->addStandardDelegate(this,0); //单点触摸

CCDirector::sharedDirector()->getTouchdispatcher()->addTargetedDelegate(this,true); //多点触摸

然后我们只需要根据要求来重写delegate函数

//多点触摸

virtual bool ccTouchBegan(CCTouch *pTouch,CCEvent *pEvent); virtual void ccTouchMoved(CCTouch *pTouch,CCEvent *pEvent); virtual void ccTouchEnded(CCTouch *pTouch,CCEvent *pEvent); virtual void ccTouchCancelled(CCTouch *pTouch,CCEvent *pEvent); //单点 virtual void cctouchesBegan(CCSet *ptouches,CCEvent *pEvent); virtual void cctouchesMoved(CCSet *ptouches,CCEvent *pEvent); virtual void cctouchesEnded(CCSet *ptouches,CCEvent *pEvent); virtual void cctouchesCancelled(CCSet *ptouches,CCEvent *pEvent);

相关文章

    本文实践自 RayWenderlich、Ali Hafizji 的文章《...
Cocos-code-ide使用入门学习地点:杭州滨江邮箱:appdevzw@1...
第一次開始用手游引擎挺激动!!!进入正题。下载资源1:从C...
    Cocos2d-x是一款强大的基于OpenGLES的跨平台游戏开发...
1.  来源 QuickV3sample项目中的2048样例游戏,以及最近《...
   Cocos2d-x3.x已经支持使用CMake来进行构建了,这里尝试...