您的位置:首页 > 移动开发 > Cocos引擎

cocos2d-x中模态对话框的一种实现方式

2014-04-08 15:12 260 查看

http://blog.csdn.net/wayne5ning/article/details/8713262


问题

典型的对话框包括按钮、表格等可以响应触摸的元素。对话框一般在场景中的最上层。模态对话框是指只有该对话框能够响应触摸操作,而其它层不能响应此操作。


分析

对话框会有两种触摸代理,一种是对话框本身,还有一种是CCMenu。cocos2d-x使用优先级来管理触摸代理,对于同一个触摸,如果有优先级数字更小的代理响应了,则优先级数字更大代理不再响应此触摸。例如,CCMenu的优先级数默认为-128。当模态对话框本身的优先级数比-128小,并且如果此触摸只要被响应了就会会吞噬掉(CCTouchDispatcher::addTargetedDelegate中第三个参数设置为true),则在此对话框中的触摸不会被下一层响应到。

然后,还有个问题是,模态对话框中的按钮也被屏蔽了。因此,解决方式之一是主动调用CCMenu的触摸方法。


解决方式

此模态对话框响应定向触摸(TargetedTouch),优先级数比-128小就行了。重写定向触摸响应方法,包括ModalDialog::ccTouchBegan, ModalDialog::ccTouchEnded, ModalDialog::ccTouchMoved 和 ModalDialog::ccTouchCancelled,并在这些方法中主动调用CCMenu的相应响应方法。需要注意的是,CCMenu在响应ccTouchEnded,ccTouchMoved 和 ccTouchCancelled时需要CCMenu::ccTouchBegan返回真,否则会出现断言错误(见CCMenu中的断言CCAssert(m_eState
== kCCMenuStateTrackingTouch, "[Menu ccTouchEnded] -- invalid state");)。因此,如果CCMenu::ccTouchBegan返回为false,则不再响应ModalDialog::ccTouchEnded, ModalDialog::ccTouchMoved 和 ModalDialog::ccTouchCancelled。大致代码如下:

[cpp] view
plaincopyprint?

class ModalDialog : public CCLayer  

{  

public:  

    CREATE_FUNC(ModalDialog);  

protected:  

    virtual bool init()  

    {  

        setTouchEnabled(true);  

  

        // 初始化m_pMenu;  

  

        return true;  

    }  

    virtual void registerWithTouchDispatcher()  

    {  

        // priority比-128小就可以了  

        CCDirector::sharedDirector()->getTouchDispatcher()  

            ->addTargetedDelegate(this, -150, true);  

    }  

    virtual bool ccTouchBegan(CCTouch *pTouch, CCEvent *pEvent)  

    {  

        m_bMenuSelected = false;  

        if (NULL != m_pMenu)  

        {  

             m_bMenuSelected = m_pMenu->ccTouchBegan(pTouch, pEvent);  

        }  

        return true;  

    }  

    virtual void ccTouchMoved(CCTouch *pTouch, CCEvent *pEvent)  

    {  

        if (NULL != m_pMenu && m_bMenuSelected)  

        {  

            m_pMenu->ccTouchMoved(pTouch, pEvent);  

        }  

    }  

    virtual void ccTouchEnded(CCTouch *pTouch, CCEvent *pEvent)  

    {  

        if (NULL != m_pMenu && m_bMenuSelected)  

        {  

            m_pMenu->ccTouchEnded(pTouch, pEvent);  

        }  

    }  

    virtual void ccTouchCancelled(CCTouch *pTouch, CCEvent *pEvent)  

    {  

        if (NULL != m_pMenu && m_bMenuSelected)  

        {  

            m_pMenu->ccTouchCancelled(pTouch, pEvent);  

        }  

    }  

  

private:  

    ModalDialog():m_pMenu(NULL){};  

    ~ModalDialog(){};  

    CCMenu* m_pMenu;  

    // 记录按钮是否被选中  

    bool m_bMenuSelected;  

};  

实际使用时,为了扩展性,可以将Menu从外面添加到对话框中。

注:cocos2d-x版本为cocos2d-2.1beta3-x-2.1.1
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: