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,0,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);



  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值