• cocos2dx基础篇(10) 按钮控件CCControlButton


    【3.x】

        (1)去掉 “CC”

        (2)对象类 CCObject 改为 Ref

        (3)按钮事件回调依旧为 cccontrol_selector ,没有使用 CC_CALLBACK_2

        (4)按钮状态 CCControlState 改为强枚举 Control::State

    //
        NORMAL            //正常
        HIGH_LIGHTED      //高亮(即在内部触摸状态下)
        DISABLED          //禁用
        SELECTED          //选中
    //

        (5)按钮事件 CCControlEvent 改为强枚举 Control::EventType

    //
        TOUCH_DOWN        //刚刚开始触摸按钮时
        DRAG_INSIDE       //在内部拖动时(保持触摸状态下)
        DRAG_OUTSIDE      //在外部拖动时(保持触摸状态下)
        DRAG_ENTER        //拖动刚进入内部时(保持触摸状态下)
        DRAG_EXIT         //拖动刚离开内部时(保持触摸状态下)
        TOUCH_UP_INSIDE   //在内部抬起手指(保持触摸状态下)
        TOUCH_UP_OUTSIDE  //在外部抬起手指(保持触摸状态下)
        TOUCH_CANCEL      //取消触点
    //

     按钮控件CCControlButton,想必大家对这个再熟悉不过了吧?每个游戏基本都会用到按钮。

    一个按钮不仅有几种不同的按钮状态,而且还有一些按钮事件。另外按钮控件CCControlButton使用的背景图片是点九图CCScale9Sprite,可以使得按钮在变大的情况下,尽量保持棱角不失真。

    1、按钮状态CCControlState

    //
        CCControlStateNormal            //正常
        CCControlStateHighlighted       //高亮(即在内部触摸状态下)
        CCControlStateDisabled          //禁用
        CCControlStateSelected          //选中
    //

    2、按钮事件CCControlEvent

    //
        CCControlEventTouchDown                 //刚刚开始触摸按钮时
        CCControlEventTouchDragInside           //在内部拖动时(保持触摸状态下)
        CCControlEventTouchDragOutside          //在外部拖动时(保持触摸状态下)
        CCControlEventTouchDragEnter            //拖动刚进入内部时(保持触摸状态下)
        CCControlEventTouchDragExit             //拖动刚离开内部时(保持触摸状态下)
        CCControlEventTouchUpInside             //在内部抬起手指(保持触摸状态下)
        CCControlEventTouchUpOutside            //在外部抬起手指(保持触摸状态下)
        CCControlEventTouchCancel               //取消触点
    //

    3、绑定按钮事件的方法

    //
        //绑定控件事件
        addTargetWithActionForControlEvents(this, cccontrol_selector(HelloWorld::touchDownAction), CCControlEventTouchDown);
        void addTargetWithActionForControlEvents(CCObject* target, SEL_CCControlHandler action, CCControlEvent controlEvents);
           
        //删除控件事件
        //removeTargetWithActionForControlEvents(this, cccontrol_selector(HelloWorld::touchDownAction), CCControlEventTouchDown);
        void removeTargetWithActionForControlEvents(CCObject* target, SEL_CCControlHandler action, CCControlEvent controlEvents);
    //

    4、需要引用的头文件及命名空间

    //
        #include "cocos-ext.h"              //包含cocos-ext.h头文件
        using namespace cocos2d::extension; //引用cocos2d::extension命名空间
    //

    5、常用操作如下

    //
    class CCControlButton : public CCControl
    {
    /**
     *     创建CCControlButton的三种方法
     */
        //使用点九图CCScale9Sprite,按钮中不带标签CCLabel
        static CCControlButton* create(CCScale9Sprite* sprite);
     
        //使用标签label,可以是CCLabelTTF、CCLabelBMFont
        static CCControlButton* create(CCNode* label, CCScale9Sprite* backgroundSprite);
     
        //title:标签内容
        //fontName:字体资源,如 "Arial"
        //fontSize:字体大小,默认 12
        //内部创建的标签为CCLabelTTF
        static CCControlButton* create(std::string title, const char* fontName, float fontSize);
     
     
    /**
     *     属性设置1(在当前CCControlState下)
     *     getCurrentTitle , getCurrentTitleColor ,
     *     TitleLabel , BackgroundSprite , PreferredSize
     */
        //当前显示的标签内容,只读getCurrentTitle
        CC_SYNTHESIZE_READONLY(CCString*, m_currentTitle, CurrentTitle);
     
        //当前显示的标签内容颜色,只读getCurrentTitleColor
        CC_SYNTHESIZE_READONLY_PASS_BY_REF(ccColor3B, m_currentTitleColor, CurrentTitleColor);
     
        //设置当前CCControlState下的标签,set/get
        CC_SYNTHESIZE_RETAIN(CCNode*, m_titleLabel, TitleLabel);
     
        //设置当前CCControlState下的背景精灵,set/get
        CC_SYNTHESIZE_RETAIN(CCScale9Sprite*, m_backgroundSprite, BackgroundSprite);
     
        //设置按钮大小,若标签label大小大于按钮,将自动扩展,set/get。
        //不过经过我的测试:设置了,反而按钮大小被固定了。没有按照label的大小进行自动伸展了。
        CC_PROPERTY(CCSize, m_preferredSize, PreferredSize);
     
     
    /**
     *     属性设置2(在指定CCControlState下)
     *     setTitleLabelForState , setTitleForState , setTitleColorForState , 
     *     setTitleTTFForState , setTitleTTFSizeForState , 
     *     setTitleBMFontForState , 
     *     setBackgroundSpriteForState , setBackgroundSpriteFrameForState , getBackgroundSpriteForState
     */
        //设置在指定CCControlState下的 字体标签
        //若未设置标签,默认为CCButtonStateNormal状态的字体标签
        //字体标签可以是CCLabelTTF、CCLabelBMFont
        virtual void setTitleLabelForState(CCNode* label, CCControlState state);
        virtual CCNode* getTitleLabelForState(CCControlState state);
     
     
        //设置在指定CCControlState下的 标签内容
        //若未设置标签,默认返回CCButtonStateNormal状态的标签内容
        virtual void setTitleForState(CCString* title, CCControlState state);
        virtual CCString* getTitleForState(CCControlState state);
     
     
        //设置在指定CCControlState下的 标签颜色
        virtual void setTitleColorForState(ccColor3B color, CCControlState state);
        virtual const ccColor3B getTitleColorForState(CCControlState state);
     
    //###############################################################################
     
        //设置在指定CCControlState下的 标签为CCLabelTTF
        //fntFile为字体资源名,如 "Arial"
        virtual void setTitleTTFForState(const char* fntFile, CCControlState state);
        virtual const char* getTitleTTFForState(CCControlState state);
     
     
        //设置在指定CCControlState下的 CCLabelTTF标签的字体大小
        virtual void setTitleTTFSizeForState(float size, CCControlState state);
        virtual float getTitleTTFSizeForState(CCControlState state);
     
    //###############################################################################
     
        //设置在指定CCControlState下的 标签为CCLabelBMFont
        //fntFile为字体资源名,如 *.fnt
        virtual void setTitleBMFontForState(const char* fntFile, CCControlState state);
        virtual const char * getTitleBMFontForState(CCControlState state);
     
    //###############################################################################
     
        //使用点九图CCScale9Sprite,设置在指定CCControlState下的 背景精灵
        virtual void setBackgroundSpriteForState(CCScale9Sprite* sprite, CCControlState state);
     
     
        //使用精灵帧CCSpriteFrame,设置在指定CCControlState下的 背景精灵
        //其实在内部实现的代码,实际上是利用精灵帧spriteFrame创建了点九图CCScale9Sprite作为背景精灵
        virtual void setBackgroundSpriteFrameForState(CCSpriteFrame* spriteFrame, CCControlState state);
     
     
        //获取在指定CCControlState下的 背景图
        virtual CCScale9Sprite* getBackgroundSpriteForState(CCControlState state);
     
     
    /**
     *     继承于父类
     */
        virtual void setEnabled(bool enabled);     //是否启用
        virtual void setSelected(bool enabled);    //是否选中
        virtual void setHighlighted(bool enabled); //是否高亮
    };
    //

    【代码实战】

     代码来源于cocos2dx的官方项目TestCpp中。

    1、按钮背景(正常、高亮)

    2、引入头文件和命名空间

    //
        #include "cocos-ext.h"
        using namespace cocos2d::extension;
    //

    3、在HelloWorld.h中声明按钮事件的回调函数、显示按钮状态的Label

    //
        CCLabelTTF* displayLabel; //显示按钮状态的label
        void touchDownAction(CCObject* sender, CCControlEvent controlEvent);        //刚刚开始触摸按钮时
        void touchDragInsideAction(CCObject* sender, CCControlEvent controlEvent);  //在内部拖动时(保持触摸状态下)
        void touchDragOutsideAction(CCObject* sender, CCControlEvent controlEvent); //在外部拖动时(保持触摸状态下)
        void touchDragEnterAction(CCObject* sender, CCControlEvent controlEvent);   //拖动刚进入内部时(保持触摸状态下)
        void touchDragExitAction(CCObject* sender, CCControlEvent controlEvent);    //拖动刚离开内部时(保持触摸状态下)
        void touchUpInsideAction(CCObject* sender, CCControlEvent controlEvent);    //在内部抬起手指(保持触摸状态下)
        void touchUpOutsideAction(CCObject* sender, CCControlEvent controlEvent);   //在外部抬起手指(保持触摸状态下)
        void touchCancelAction(CCObject* sender, CCControlEvent controlEvent);      //取消触点
    //

    4、在HelloWorld.cpp的init中创建按钮,并绑定按钮事件

    //
        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);
     
     
        //显示按钮状态的标签displayLabel
            displayLabel = CCLabelTTF::create("No Event", "Marker Felt", 32);
            displayLabel->setPosition( midPos + ccp(0, 100) );
            this->addChild(displayLabel);
     
     
        //按钮中的背景精灵CCScale9Sprite
            CCScale9Sprite* bgNormal = CCScale9Sprite::create("btnNormal.png");           //正常背景
            CCScale9Sprite* bgHighlighted = CCScale9Sprite::create("btnHighlighted.png"); //高亮背景
     
        //按钮中的标签CCLabelTTF
            CCLabelTTF* titleNormal = CCLabelTTF::create("Button is Normal !", "Marker Felt", 30);
            CCLabelTTF* titleHighlighted = CCLabelTTF::create("Button is Highlighted !", "Marker Felt", 30);
     
     
        //创建按钮CCControlButton
            CCControlButton* btn = CCControlButton::create(titleNormal, bgNormal);
            btn->setPosition( midPos );
            this->addChild(btn);
     
        //设置按钮高亮时的状态
            btn->setTitleLabelForState(titleHighlighted, CCControlStateHighlighted);    //高亮标签
            btn->setTitleColorForState(ccRED, CCControlStateHighlighted);               //红色
            btn->setBackgroundSpriteForState(bgHighlighted, CCControlStateHighlighted); //高亮背景
     
            //写了这句话,反而大小被固定了。没有按照label的大小进行自动伸展了
            //btn->setPreferredSize( CCSizeMake(120,40) );
     
        //绑定事件,用于显示按钮状态
            btn->addTargetWithActionForControlEvents(this, cccontrol_selector(HelloWorld::touchDownAction), CCControlEventTouchDown);               //刚刚开始触摸按钮时
            btn->addTargetWithActionForControlEvents(this, cccontrol_selector(HelloWorld::touchDragInsideAction), CCControlEventTouchDragInside);   //在内部拖动时(保持触摸状态下)
            btn->addTargetWithActionForControlEvents(this, cccontrol_selector(HelloWorld::touchDragOutsideAction), CCControlEventTouchDragOutside); //在外部拖动时(保持触摸状态下)
            btn->addTargetWithActionForControlEvents(this, cccontrol_selector(HelloWorld::touchDragEnterAction), CCControlEventTouchDragEnter);     //拖动刚进入内部时(保持触摸状态下)
            btn->addTargetWithActionForControlEvents(this, cccontrol_selector(HelloWorld::touchDragExitAction), CCControlEventTouchDragExit);       //拖动刚离开内部时(保持触摸状态下)
            btn->addTargetWithActionForControlEvents(this, cccontrol_selector(HelloWorld::touchUpInsideAction), CCControlEventTouchUpInside);       //在内部抬起手指(保持触摸状态下)
            btn->addTargetWithActionForControlEvents(this, cccontrol_selector(HelloWorld::touchUpOutsideAction), CCControlEventTouchUpOutside);     //在外部抬起手指(保持触摸状态下)
            btn->addTargetWithActionForControlEvents(this, cccontrol_selector(HelloWorld::touchCancelAction), CCControlEventTouchCancel);           //取消触点
     
            return true;
        }
    //

    5、实现按钮事件的回调函数

    //
        //刚刚开始触摸按钮时
        void HelloWorld::touchDownAction(CCObject *senderz, CCControlEvent controlEvent)
        {
            displayLabel->setString("Touch Down");
        }
     
        //在内部拖动时(保持触摸状态下)
        void HelloWorld::touchDragInsideAction(CCObject *sender, CCControlEvent controlEvent)
        {
            displayLabel->setString("Drag Inside");
        }
     
        //在外部拖动时(保持触摸状态下)
        void HelloWorld::touchDragOutsideAction(CCObject *sender, CCControlEvent controlEvent)
        {
            displayLabel->setString("Drag Outside");
        }
     
        //拖动刚进入内部时(保持触摸状态下)
        void HelloWorld::touchDragEnterAction(CCObject *sender, CCControlEvent controlEvent)
        {
            displayLabel->setString("Drag Enter");
        }
     
        //拖动刚离开内部时(保持触摸状态下)
        void HelloWorld::touchDragExitAction(CCObject *sender, CCControlEvent controlEvent)
        {
            displayLabel->setString("Drag Exit");
        }
     
        //在内部抬起手指(保持触摸状态下)
        void HelloWorld::touchUpInsideAction(CCObject *sender, CCControlEvent controlEvent)
        {
            displayLabel->setString("Touch Up Inside.");
        }
     
        //在外部抬起手指(保持触摸状态下)
        void HelloWorld::touchUpOutsideAction(CCObject *sender, CCControlEvent controlEvent)
        {
            displayLabel->setString("Touch Up Outside.");
        }
     
        //取消所有触摸
        void HelloWorld::touchCancelAction(CCObject *sender, CCControlEvent controlEvent)
        {
            displayLabel->setString("Touch Cancel");
        }
    //

    6、运行结果

    wKioL1P2M7nypRzJABsPKqwUVDg336.gif

    7、分析与总结

        (1)本来一个这么小的按钮图片,这么变这么大了呢?这是因为当标签CCLabelTTF的大小大于按钮大小时,按钮就会自动进行伸展。

        (2)按钮事件:

            CCControlEventTouchDragEnter     //拖动刚进入内部时(保持触摸状态下)

            CCControlEventTouchDragExit      //拖动刚离开内部时(保持触摸状态下)

            只有在正好进入或离开按钮内部时才看得到效果,手一抖就变成DragInside或DragOutside了。

  • 相关阅读:
    基于Linux OpenJDK Debian的发行版的JAVA_HOME环境变量的正确目标是什么?
    redhat linux卸载默认的openjdk与安装sun的jdk
    更换介质:请把标有…… DVD 的盘片插入驱动器“/media/cdrom/”再按回车键“ 解决方法
    mysql 导出表结构和表数据 mysqldump用法
    转怎么让VI支持中文显示
    debian 更换sh的默认链接为bash
    基于percona-monitoring-plugins实现Zabbix的MySQL多端口自动发现监控
    elasticsearch中client.transport.sniff的使用方法和注意事项
    网络大数据分析 -- 使用 ElasticSearch + LogStash + Kibana 来可视化网络流量
    Parsing Netflow using Kibana via Logstash to ElasticSearch
  • 原文地址:https://www.cnblogs.com/lmx282110xxx/p/10798731.html
Copyright © 2020-2023  润新知