zoukankan      html  css  js  c++  java
  • cocos2dx基础篇(5) 按钮

    这篇是直接复制的别人的,太多了,难得写。。。

    【本节内容】

    CCMenu、CCMenuItem其具体的六个子类


    【菜单CCMenu】

    菜单CCMenu是用来装载菜单按钮的图层,图层中的子节点只能够是菜单项CCMenuItem或其子类。一般我们先创建菜单项CCMenuItem,然后使用一个或多个菜单项生成菜单CCMenu,最后把CCMenu加入当前图层。

    由于CCMenu的父类为CCLayer,锚点为(0,0),无法设置锚点。CCMenu的默认原点坐标为屏幕正中心(winSize.width/2, winSize.height/2)。

        CCMenuItem是添加在CCMenu层中的,所以CCMenuItem的位置是相对于CCMenu层的偏移位置。CCMenuItem相对于CCMenu的偏移量默认为(0,0),且菜单项的锚点默认为(0.5,0.5)。

    常用操作:

    class CC_DLL CCMenu : public CCLayerRGBA
    {
    /**
     *     创建菜单的三个常用方法
     */
        //创建一个空菜单
        static CCMenu* create();
     
        //CCMenu::create(item1,item2,item3,NULL);
        //用CCMenuItem菜单项创建菜单,最后以NULL表示结束.
        static CCMenu* create(CCMenuItem* item, ...);
     
        //用一个包含CCMenuItem的CCArray数组来创建菜单
        static CCMenu* createWithArray(CCArray* pArrayOfItems);
     
     
    /**
     *     菜单布局方式
     *     注意:使用以下函数进行菜单布局时,将会把整体菜单项的相对于CCMenu的偏移坐标设置到(0,0)。
     *             所以布局后,应该设置CCMenu菜单的坐标为屏幕正中心(winSize.width/2, winSize.height/2),效果更加。
     *     alignItemsVertically , alignItemsHorizontally , 
     *     alignItemsInColumns , alignItemsInRows
     */
        //让menu的所有item竖着布局
        //item1
        //item2
        //item3
        void alignItemsVertically(); //默认间隙:5个像素
        void alignItemsVerticallyWithPadding(float padding); //相连两个item间隔为padding
     
     
        //让menu的所有item横着布局
        //item1  item2    item3
        void alignItemsHorizontally(); //默认间隙:5个像素
        void alignItemsHorizontallyWithPadding(float padding); //相连两个item间隔为padding
     
     
        //将items进行分组,然后按列(columns)进行排列
        //每一组在同一行,参数columns表示每一组的菜单项个数,并以NULL表示结束。
        //alignItemsInColumns(3,2,1,NULL);
        //item1 item2 item3
        //  item4 item5
        //      item6
        void alignItemsInColumns(unsigned int columns, ...);
     
     
        //将items进行分组,然后按行(rows)进行排列。与上述类似。
        //alignItemsInRows(3,2,1,NULL);
        //item1
        //          item4
        //item2                 item6
        //          item5
        //item3
        void alignItemsInRows(unsigned int rows, ...);
     
     
    /**
     *     添加、删除item菜单项
     *     addChild , removeChild
     */
        virtual void addChild(CCNode * child);
        virtual void addChild(CCNode * child, int zOrder);
        virtual void addChild(CCNode * child, int zOrder, int tag);
        virtual void removeChild(CCNode* child, bool cleanup);
     
     
    /**
     *     设置菜单是否可用
     *     setEnabled
     */
        virtual void setEnabled(bool value) { m_bEnabled = value; };
        virtual bool isEnabled() { return m_bEnabled; }
    };

    【菜单项CCMenuItem】

        菜单项的子类可以分成三类,总共六个:

            (1)文字菜单项:CCMenuItemLabel、CCMenuItemAtlasFont、CCMenuItemFont;

            (2)图片菜单项:CCMenuItemSprite、CCMenuItemImage;

            (3)切换菜单项:CCMenuItemToggle

        作为其它菜单项的父类,主要提供了一下三个功能:

            (1)提供了基本按钮的状态:正常、选中、禁用。

            (2)为按钮实现了基本的回调函数机制。当玩家点积按钮后,就会调用执行相应的回调函数。

            (3)触碰菜单项,附有自动放大效果

    CCMenuItemLabel

        CCMenuItemLabel是一个包含了文字标签的菜单项按钮,CCLabel的三个标签CCLabelBMFont ,CCLabelAtlas,CCLabelTTF对象,都可以放置在该按钮对象中。

    常用操作:

    class CC_DLL CCMenuItemLabel : public CCMenuItem
    {
    /**
     *     创建CCMenuItemLabel
     *     支持字体标签类:CCLabelBMFont , CCLabelAtlas , CCLabelTTF 
     */
        //用label字体标签创建,不设置回调响应事件。
        //label可以是CCLabelBMFont , CCLabelAtlas , CCLabelTTF三种文字标签。
        static CCMenuItemLabel* create(CCNode *label);
     
        //用label字体标签创建,并设置回调响应事件。
        //      target:执行当前按钮的对象,一般为this。表示由CCLayer图层执行回调响应事件。
        //      selector:使用菜单回调函数menu_selector。一般在当前CCLayer图层中定义。
        //create( label, this , menu_selector( HelloWorld::func1 ) );
        static CCMenuItemLabel * create(CCNode*label, CCObject* target, SEL_MenuHandler selector);
     
     
    /**
     *     属性设置
     *     setString , setEnabled , setDisabledColor , setLabel
     */
        //设置内部字体标签(CCLabel)的显示文字内容
        void setString(const char * label);
     
        //设置该CCMenuItemLabel对象是否可用
        virtual void setEnabled(bool enabled);
        virtual bool isSelected();
     
        //禁用时的颜色
        virtual void setDisabledColor(ccColor3B&);
        virtual const ccColor3B& getDisabledColor();
     
        //被渲染的字体,可以是CCLabelBMFont , CCLabelAtlas , CCLabelTTF。
        virtual void setLabel(CCNode*);
        virtual CCNode* getLabel();
    };

    2 CCMenuItemAtlasFont

    CCMenuItemAtlasFont的父类为CCMenuItemLabel。和父类的区别在于:该类在创建时,只要设置显示内容、使用的字体资源.png即可。它默认使用CCLabelAtlas来创建文字标签的菜单项按钮。而省去了父类创建label的步骤。

    常用操作:

    class CC_DLL CCMenuItemFont : public CCMenuItemLabel
    {
    /**
     *     创建CCMenuItemFont
     */
        //创建基于CCLabelAtlas字体标签的CCMenuItemAtlasFont,不带回调响应事件。
        //create("20140818" , "digit.png" , 20 , 20 , '0' );
        //create("20140818" , "digit.png" , 20 , 20 , '0' , this , menu_selector( HelloWorld::func2 ) );
        static CCMenuItemAtlasFont* create(const char *value, const char *charMapFile, int itemWidth, int itemHeight, char startCharMap);
        static CCMenuItemAtlasFont* create(const char *value, const char *charMapFile, int itemWidth, int itemHeight, char startCharMap, CCObject* target, SEL_MenuHandler selector);
    };

    CCMenuItemFont

       CCMenuItemAtlasFont的父类为CCMenuItemLabel。和父类的区别在于:该类在创建时,只要设置显示内容即可。它默认使用CCLabelTTF来创建文字标签的菜单项按钮。而省去了父类创建label的步骤。和父类相比,可以设置字体大小。

    常用操作:

    class CC_DLL CCMenuItemFont : public CCMenuItemLabel
    {
    /**
     *     创建CCMenuItemFont
     */
        //create(要显示的字符串)
        //create(要显示的字符串,执行当前按钮的对象,回调函数)
        //      target:执行当前按钮的对象,一般为this。表示由CCLayer图层执行回调响应事件。
        //      selector:使用菜单回调函数menu_selector。一般在当前CCLayer图层中定义。
        //create( "hello" , this , menu_selector( HelloWorld::func3 ) );
        static CCMenuItemFont * create(const char *value);
        static CCMenuItemFont * create(const char *value, CCObject* target, SEL_MenuHandler selector);
     
         
    /**
     *     属性设置
     */
        //这是一个全局静态方法,用来设置新创建CCMenuItemFont时的默认字体大小的
        //在不进行设置时,创建的CCMenuItemFont,默认大小为32。
        //CCMenuItemFont::setFontSize(32);
        static void setFontSize(unsigned int s);
        static unsigned int fontSize();
     
        //这是一个全局静态方法,用来设置新创建CCMenuItemFont时的默认字体资源.fnt的
        //在不进行设置时,创建的CCMenuItemFont,默认字体为"Marker Felt"。
        //CCMenuItemFont::setFontName("Arial");
        static void setFontName(const char *name);
        static const char *fontName();
     
        //设置该对象的字体大小及使用的字体资源名.fnt
        void setFontSizeObj(unsigned int s);
        unsigned int fontSizeObj();
        void setFontNameObj(const char* name);
        const char* fontNameObj();
    };

    CCMenuItemSprite

        CCMenuItemSprite是一个由精灵对象组成的菜单按钮。此类的内部属性提供了三个精灵对象,分别表示按钮的三个状态:正常、选中、禁用。每种状态都分别对应了一个精灵图片。 精灵是引擎中最为丰富和自由的元素,因此类CCMenuItemSprite算得上是将精灵和按钮功能的结合体。

    常用操作:

    class CC_DLL CCMenuItemSprite : public CCMenuItem
    {
    /**
     *     创建CCMenuItemSprite
     */
        //参数:
        //      normalSprite:  正常时的默认精灵normalSprite
        //      selectedSprite:被选中时的精灵selectedSprite
        //      disabledSprite:禁用时的精灵disabledSprite
        //      target:执行当前按钮的对象,一般为this。表示由CCLayer图层执行回调响应事件。
        //      selector:使用菜单回调函数menu_selector。一般在当前CCLayer图层中定义。
        //CCSprite* normalSprite = CCSprite::create("sp1.png");
        //CCSprite* selectedSprite = CCSprite::create("sp2.png");
        //CCSprite* disabledSprite = CCSprite::create("sp3.png");
        //create(normalSprite, selectedSprite, disabledSprite, this, menu_selector(HelloWorld::func4) );
        static CCMenuItemSprite * create(CCNode* normalSprite, CCNode* selectedSprite, CCNode* disabledSprite = NULL);
        static CCMenuItemSprite * create(CCNode* normalSprite, CCNode* selectedSprite, CCObject* target, SEL_MenuHandler selector);
        static CCMenuItemSprite * create(CCNode* normalSprite, CCNode* selectedSprite, CCNode* disabledSprite, CCObject* target, SEL_MenuHandler selector);
     
     
    /**
     *     设置三种状态的精灵CCSprite
     */
        //正常时的默认图片normalSprite
        //被选中时的图片selectedSprite
        //禁用时的图片disabledSprite
        virtual void setNormalImage(CCNode* normalSprite);
        virtual CCNode* getNormalImage();
        virtual void setSelectedImage(CCNode* selectedSprite);
        virtual CCNode* getSelectedImage();
        virtual void setDisabledImage(CCNode* disabledSprite);
        virtual CCNode* getDisabledImage();
     
     
    /**
     *     设置选中、禁用
     */
        virtual void selected(); //选中
        virtual void unselected(); //取消选中
        virtual void setEnabled(bool bEnabled); //是否启用。false禁用。
    };

    CCMenuItemImage

       CCMenuItemImage继承自CCMenuItemSprite,并没有太大的变化。只是提供了更为简捷的方式,将原本按钮中的精灵对象换为了三张纹理图片。无需创建精灵对象,就可以直接创建一个精灵按钮对象。与父类相比,省去了创建CCSprite精灵对象的过程。实际上在create创建的过程中,已经帮你做了创建CCSprite的过程了。

    常用操作:

    class CC_DLL CCMenuItemImage : public CCMenuItemSprite
    {
    /**
     *     创建CCMenuItemImage
     */
        //与CCMenuItemSprite创建方式差不多。就是参数变成了图片资源(如*.png)
        //create("sp1.png", "sp2.png", "sp3.png", this, menu_selector(HelloWorld::func5) );
        static CCMenuItemImage* create(const char *normalImage, const char *selectedImage);
        static CCMenuItemImage* create(const char *normalImage, const char *selectedImage, const char *disabledImage);
        static CCMenuItemImage* create(const char *normalImage, const char *selectedImage, CCObject* target, SEL_MenuHandler selector);
        static CCMenuItemImage* create(const char *normalImage, const char *selectedImage, const char *disabledImage, CCObject* target, SEL_MenuHandler selector);
     
    /**
     *     属性设置
     */
        //用CCSpriteFrame精灵帧,设置正常时的精灵帧Normal
        void setNormalSpriteFrame(CCSpriteFrame* frame);
        //用CCSpriteFrame精灵帧,设置选中时的精灵帧Selected
        void setSelectedSpriteFrame(CCSpriteFrame* frame);
        //用CCSpriteFrame精灵帧,设置禁用时的精灵帧Disabled
        void setDisabledSpriteFrame(CCSpriteFrame* frame);
    };

    CCMenuItemToggle

    CCMenuItemToggle是比较特殊的。它在内部拥有一个CCMenuItem菜单项数组,用来负责展示不同的菜单项按钮状态。因为使用了一个菜单按钮的数组,所以此类的对象可以实现状态的切换。此类是一个菜单项按钮对象的集合,能够包含很多的菜单项按钮状态,方便开发者进行切换。 例如,CCMenuItemToggle可以用来做开关按钮。

    class CC_DLL CCMenuItemToggle : public CCMenuItem
    {
    /**
     *     创建CCMenuItemToggle
     *     create 或 createWithTarget
     */
        //使用一个菜单项创建CCMenuItemToggle对象
        //CCMenuItemFont* item = CCMenuItemFont::create("hello");
        //CCMenuItemToggle::create(item);
        static CCMenuItemToggle* create(CCMenuItem *item);
     
        //使用菜单项参数列表创建,以NULL结束列表
        //item1 = CCMenuItemFont::create("hello");
        //item2 = CCSprite::create("sp1.png"):
        //createWithTarget(this, menu_selector(HelloWorld::func6), item1, item2, NULL);
        static CCMenuItemToggle* createWithTarget(CCObject* target, SEL_MenuHandler selector, CCMenuItem* item, ...);  
     
        //使用包含菜单项的数组创建
        //createWithTarget(this, menu_selector(HelloWorld::func6), pArray);
        static CCMenuItemToggle * createWithTarget(CCObject* target, SEL_MenuHandler selector, CCArray* menuItems);
     
     
    /**
     *     菜单项数组集合相关
     *     setSelectedIndex , selectedItem ,
     *     setSubItems , addSubItem
     */
        //设置当前选中的CCMenuItem的索引值(即数组下标)
        virtual void setSelectedIndex(unsigned int );
        virtual unsigned int getSelectedIndex();
     
        //返回当前选中的菜单项
        CCMenuItem* selectedItem(); 
     
        //设置CCMenuItem菜单项数组集合
        virtual void setSubItems(CCArray* );
        virtual CCArray* getSubItems();
     
        //添加新的子菜单项
        void addSubItem(CCMenuItem *item); 
    };

    代码实操:

    在HelloWorldScene.h中添加如下两个回调函数

    
    //添加回调响应函数
    void menuItemFont2Func(CCObject* sender); //更改标签内容
    void menuItemToggleFunc(CCObject* sender); //更改状态:正常,选中,禁用

    编写测试代码

    //
        bool HelloWorld::init()
        {
            if ( !CCLayer::init() )
            {
                return false;
            }
             
        //获取可视区域尺寸大小
            CCSize mysize = CCDirector::sharedDirector()->getVisibleSize();
        //获取可视区域的原点位置
            CCPoint origin = CCDirector::sharedDirector()->getVisibleOrigin();
        //屏幕正中心位置
            CCPoint midPos = ccp(mysize.width/2, mysize.height/2);
     
     
     
        /*
         * 创建CCMenuItemLabel
         *     使用CCLabelTTF创建
         */
            CCLabelTTF* lb1 = CCLabelTTF::create("aaaaaa", "Arial", 32);
            CCMenuItemLabel* menuItemLabel = CCMenuItemLabel::create(lb1);
            //设置位置
            menuItemLabel->setPosition( ccp(120, mysize.height-50) ); 
     
        /*
         * 创建CCMenuItemAtlasFont
         *     创建方式与CCLabelAtlas类似
         */
            CCMenuItemAtlasFont* menuItemAtlas = CCMenuItemAtlasFont::create("20140818", "fonts/digit.png", 20, 20, '0');
            menuItemAtlas->setPosition( ccp(120, mysize.height-120) );
     
     
        /*
         * 创建CCMenuItemFont
         *     创建了两个,有无附带回调响应函数
         */
            //设置CCMenuItemFont创建时的默认字体大小
            CCMenuItemFont::setFontSize(50);
     
            //不带回调响应函数,tag编号为1
            CCMenuItemFont* menuItemFont1 = CCMenuItemFont::create("11111");
            menuItemFont1->setTag(1);
     
            //触碰后,执行回调函数menuItemFont2Func。更改menuItemFont1的内容
            CCMenuItemFont* menuItemFont2 = CCMenuItemFont::create("Change1", this, menu_selector(HelloWorld::menuItemFont2Func) ); //回调
             
            menuItemFont2->setFontSizeObj(32); //设置字体大小
            menuItemFont1->setPosition( ccp(120, mysize.height-190) ); //设置位置
            menuItemFont2->setPosition( ccp(120, mysize.height-260) ); //设置位置
     
     
        /*
         * 创建CCMenu,tag编号为100
         *     菜单项menuItemLabel, menuItemAtlas, menuItemFont1, menuItemFont2
         */
            CCMenu* menu = CCMenu::create(menuItemLabel, menuItemAtlas, menuItemFont1, menuItemFont2, NULL);
             
            //设置位置为(0,0),与HelloWorld层重合
            menu->setPosition(CCPointZero); 
             
            //将CCMenu菜单添加到CCLayer中, tag编号为100
            this->addChild(menu, 0, 100); 
     
     
        /*
         * 创建CCMenuItemSprite
         *     参数为CCSprite精灵
         */
            CCSprite* sp1 = CCSprite::create("sp1.png");
            CCSprite* sp2 = CCSprite::create("sp2.png");
            CCSprite* sp3 = CCSprite::create("sp3.png");
            CCMenuItemSprite* menuItemSprite = CCMenuItemSprite::create(sp1, sp2, sp3 );
     
            menuItemSprite->setPosition( ccp(mysize.width/2 + 50, mysize.height/2 + 50) );
            menu->addChild(menuItemSprite); //添加到菜单层中
            menuItemSprite->setTag(2); //tag编号为2
     
        /*
         * 创建CCMenuItemImage
         *     参数变成纹理图片png
         */
            //使用CCMenuItemImage创建一个关闭程序的菜单项按钮
            CCMenuItemImage* menuItemImage = CCMenuItemImage::create("CloseNormal.png", "CloseSelected.png", this, menu_selector(HelloWorld::menuCloseCallback) ); //回调
            menuItemImage->setPosition( ccp(mysize.width - 40, mysize.height - 40) );
            menu->addChild(menuItemImage); //添加到菜单层中
     
     
        /*
         * 创建CCMenuItemToggle
         *     参数为CCMenuItem子类
         */
            CCMenuItemFont::setFontSize(20);
            CCMenuItemFont* menuItemFont3 = CCMenuItemFont::create("Toggle_Normal");
            CCMenuItemFont* menuItemFont4 = CCMenuItemFont::create("Toggle_Selected");
            CCMenuItemImage* menuItemImage2 = CCMenuItemImage::create("sp3.png", "sp1.png");
             
            //创建CCMenuItemToggle,回调函数:更改menuItemSprite的状态。
            CCMenuItemToggle* menuItemToggle = CCMenuItemToggle::createWithTarget(this, menu_selector(HelloWorld::menuItemToggleFunc), 
                                                                                        menuItemFont3, menuItemFont4, NULL ); //菜单项参数列表
            menuItemToggle->setPosition( ccp(mysize.width/2 + 50, mysize.height/2 - 50) ); //设置位置
     
            //将menuItemImage2添加到menuItemToggle中
            menuItemToggle->addSubItem(menuItemImage2);
     
            menu->addChild(menuItemToggle); //添加到菜单层中
     
     
            return true;
        }
    //

    编写回调响应函数的代码

    //
        /*
         *     回调函数menuItemFont2Func
         */
     
        //变化menuItemFont1的内容
        void HelloWorld::menuItemFont2Func(CCObject* sender)
        {
             
        //获取menuItemFont2
            CCMenuItemFont* menuItemFont2 = (CCMenuItemFont*)sender;
     
        //从CCLayer中获取CCMenu菜单
            CCMenu* menu = (CCMenu*)this->getChildByTag(100);
     
        //获取menuItemFont1,其tag为1
            //!!!注意!!!
            //      tag是相对父节点而言的:this的子节点中没有tag为1,而menuItemFont1是menu中tag为1的子节点。
            CCMenuItemFont* menuItemFont1 = (CCMenuItemFont*)menu->getChildByTag(1);
             
     
        //更改menuItemFont1的内容
            //获取menuItemFont2显示的标签内容
            CCLabelTTF* lb = (CCLabelTTF*)menuItemFont2->getLabel();
     
            //strcmp判断是否等于Change1
            if( strcmp( lb->getString() , "Change1") == 0 ) { 
                lb->setString("Change2");
                menuItemFont1->setString("22222");
            }else {
                lb->setString("Change1");
                menuItemFont1->setString("11111");
            }
        }
     
     
        /*
         *     回调函数menuItemToggleFunc
         */
     
        //更改状态:正常,选中,禁用
        void HelloWorld::menuItemToggleFunc(CCObject* sender)
        {
             
        //获取menuItemToggle
            CCMenuItemToggle* menuItemToggle = (CCMenuItemToggle*)sender;
     
        //从CCLayer中获取CCMenu菜单
            CCMenu* menu = (CCMenu*)this->getChildByTag(100);
     
        //获取menuItemSprite
            CCMenuItemSprite* menuItemSprite = (CCMenuItemSprite*)menu->getChildByTag(2);
     
     
        //根据menuItemToggle当前被选中的是哪一项,来设置menuItemSprite的状态
            switch( menuItemToggle->getSelectedIndex() ) {
                case 0: //正常
                    menuItemSprite->setEnabled(true);
                    break;
                case 1: //选中
                    menuItemSprite->selected();
                    break;
                case 2: //禁用
                    menuItemSprite->setEnabled(false);
                    break;
            }
        }
        //

    运行结果:

    wKioL1PyIOjQRL_uAAC3xFJM1q4920.jpg

  • 相关阅读:
    宏与函数
    随笔
    随笔
    GS与MS之间通信
    关于function的一种常用用法
    12 应该提取的奖金是
    11 多少个互不相同且无重复数字的三位数
    Servlet.service() for servlet UserServlet threw exception java.lang.NullPointerException 空指针异常
    10 一球从100米高度自由落下的问题
    9 完数求解
  • 原文地址:https://www.cnblogs.com/lmx282110xxx/p/10798737.html
Copyright © 2011-2022 走看看