cocos2d-x中层和菜单的触摸控制

来源:互联网 发布:室内温度检测软件 编辑:程序博客网 时间:2024/06/14 02:05

首先是层CCLayer,其实CCLayer已经继承了触摸委托类了

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


这样一来只要重写它的方法便可处理相应的触摸操作:

class CC_DLL CCLayer : public CCNode, public CCTouchDelegate, public CCAccelerometerDelegate, public CCKeypadDelegate{public:    ...        // default implements are used to call script callback if exist    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);    // default implements are used to call script callback if exist    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);        virtual void registerWithTouchDispatcher(void);//注册触摸监听           virtual bool isTouchEnabled();//是否开启触摸    virtual void setTouchEnabled(bool value);//设置该层是否允许触摸        virtual void setTouchMode(ccTouchesMode mode);//设置触摸模式    virtual int getTouchMode();//获取触摸模式        /** priority of the touch events. Default is 0 */    virtual void setTouchPriority(int priority)//设置触摸优先级    virtual int getTouchPriority();//获取触摸优先级    ...protected:       bool m_bTouchEnabled;//记录是否允许触摸    ...    private:    ...        int m_nTouchPriority;//记录触摸优先级    ccTouchesMode m_eTouchMode;//记录触摸模式        ...};
其实要开启该层的触摸只要调用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);//从分发器中移除,关闭触摸            }        }    }}
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_nTouchPriority为0        }    }}
默认情况下层开启的是标准触摸,如果要改成目标触摸,设置该层的触摸模式即可,即调用setTouchMode方法。

当然当层被移除时要从分发器中移除触摸事件,如果有开启触摸的话:

void CCLayer::onExit(){    CCDirector* pDirector = CCDirector::sharedDirector();    if( m_bTouchEnabled )//如果开启了触摸    {        pDirector->getTouchDispatcher()->removeDelegate(this);//移除触摸        // [lua]:don't unregister script touch handler, or the handler will be destroyed        // unregisterScriptTouchHandler();    }    // remove this layer from the delegates who concern Accelerometer Sensor    if (m_bAccelerometerEnabled)    {        pDirector->getAccelerometer()->setDelegate(NULL);    }    // remove this layer from the delegates who concern the keypad msg    if (m_bKeypadEnabled)    {        pDirector->getKeypadDispatcher()->removeDelegate(this);    }    CCNode::onExit();}


其次是菜单的触摸操作。菜单是继承自于CCLayerRGBA,而CCLayerRGBA又继承自与CCLayer,所有菜单同样是继承了触摸委托类。

class CC_DLL CCMenu : public CCLayerRGBA
class CC_DLL CCLayerRGBA : public CCLayer, public CCRGBAProtocol

默认情况下,菜单的触摸优先级非常高,是-128,被声明在一个枚举中

enum {    //* priority used by the menu for the event handler    kCCMenuHandlerPriority = -128,//菜单默认的触摸优先级};

菜单的触摸实现几乎跟层的一样,只不过菜单默认是开启触摸的,而层是没有开启,需要手动开启,并也已经重写触摸的4个操作方法

    virtual bool ccTouchBegan(CCTouch* touch, CCEvent* event);    virtual void ccTouchEnded(CCTouch* touch, CCEvent* event);    virtual void ccTouchCancelled(CCTouch *touch, CCEvent* event);    virtual void ccTouchMoved(CCTouch* touch, CCEvent* event);
这样一来开发者就无需去处理这些触摸方法,所以在初始化菜单就已经帮我们开启了触摸,设置为目标触摸和并带有吞噬。
bool CCMenu::init(){    return initWithArray(NULL);}bool CCMenu::initWithArray(CCArray* pArrayOfItems){    if (CCLayer::init())    {        setTouchPriority(kCCMenuHandlerPriority);//设置菜单的触摸优先级(kCCMenuHandlerPriority = -128)        setTouchMode(kCCTouchesOneByOne);//设置菜单的触摸模式为目标触摸,并带有吞噬        setTouchEnabled(true);//开启触摸        m_bEnabled = true;//记录已开启触摸        ...                return true;    }    return false;}
同样,在移除菜单也要把触摸事件从分发器中移除:

void CCMenu::onExit(){    if (m_eState == kCCMenuStateTrackingTouch)    {        if (m_pSelectedItem)        {            m_pSelectedItem->unselected();            m_pSelectedItem = NULL;        }                m_eState = kCCMenuStateWaiting;    }    CCLayer::onExit();//调用父类的onExit,它会帮菜单将触摸事件从分发器中移除掉,取消掉触摸监听}

所以只要理解了触摸原理,如何处理这些触摸事件简直就是很easy!



0 0
原创粉丝点击