cocos2d-x 菜鸟学习笔记八(界面控件之CCControl控件)

来源:互联网 发布:网络开发技术 编辑:程序博客网 时间:2024/06/06 01:41

CCControl控件也是cocos2d-x扩展控件中的一部分,包含了九宫格(nine pacth)按钮、滑动条、开关按钮、电位计按钮、步进器和颜色选择控件,这些也算是常用的控件了,下面是各个控件的使用方法及流程:

1.九宫格按钮

这是一种为了方便不失真缩放而诞生出的简洁型按钮,具体说来就是这种按钮使用的是纹理相对比较规则的图片,然后将图片划分为九个显示区域,在缩放按钮的时候,根据需要将这九个区域中的纹理按最佳比例进行延伸或者缩放,最后达到降低、甚至不失真的缩放效果。对应九宫格的类是CCScale9Sprite,它继承的是CCNodeRGBA,就是它负责将需要的图片按3X3的等份划分出九个区域,然后搭配CCControlButton这个按钮类即可制作出九宫格按钮,下面是官方原例Extension Test里抽出修改的代码:

//我把原来用的场景改成了层class CCControlButtonTest_Event : public CCLayer{public:    bool init();    //这里定义了button的触摸事件    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);protected:    CC_SYNTHESIZE_RETAIN(CCLabelTTF *, m_pDisplayValueLabel, DisplayValueLabel)    CONTROL_SCENE_CREATE_FUNC(CCControlButtonTest_Event)};

bool CCControlButtonTest_Event::init() {bool bRet = false;    do     {        //////////////////////////////////////////////////////////////////////////        // super init first        //////////////////////////////////////////////////////////////////////////        CC_BREAK_IF(! CCLayer::init());CCSize Size = CCDirector::sharedDirector()->getWinSize();        // Add the button 这里先设定了两个九宫格用来划分不同状态下按钮的图片区块        CCScale9Sprite *backgroundButton = CCScale9Sprite::create("button.png");        CCScale9Sprite *backgroundHighlightedButton = CCScale9Sprite::create("buttonHighlighted.png");        //这个label是用来做caption标题的        CCLabelTTF *titleButton = CCLabelTTF::create("Touch Me!", "Marker Felt", 30);        titleButton->setColor(ccc3(159, 168, 176));        //这里开始加入button控件,创建时引用了label和CCScale9Sprite        CCControlButton *controlButton = CCControlButton::create(titleButton, backgroundButton);        //这里用来设置按钮被触发状态(高亮状态)时的标题颜色和图片,这里可以看到引用的是另一个CCScale9Sprite         //在源码中还能看到其它状态的设置如:CCControlStateSelected、CCControlStateDisabled        controlButton->setBackgroundSpriteForState(backgroundHighlightedButton, CCControlStateHighlighted);        controlButton->setTitleColorForState(ccWHITE, CCControlStateHighlighted);        //这里设置了锚点,用来设定按钮状态变化时的中心坐标        controlButton->setAnchorPoint(ccp(0.5f, 1));        controlButton->setPosition(ccp(Size.width / 2.0f,Size.height / 2.0f));        addChild(controlButton, 1);// Sets up event handlers 一大片触发事件,有点眼花……        controlButton->addTargetWithActionForControlEvents(this, cccontrol_selector(CCControlButtonTest_Event::touchDownAction), CCControlEventTouchDown);        controlButton->addTargetWithActionForControlEvents(this, cccontrol_selector(CCControlButtonTest_Event::touchDragInsideAction), CCControlEventTouchDragInside);        controlButton->addTargetWithActionForControlEvents(this, cccontrol_selector(CCControlButtonTest_Event::touchDragOutsideAction), CCControlEventTouchDragOutside);        controlButton->addTargetWithActionForControlEvents(this, cccontrol_selector(CCControlButtonTest_Event::touchDragEnterAction), CCControlEventTouchDragEnter);        controlButton->addTargetWithActionForControlEvents(this, cccontrol_selector(CCControlButtonTest_Event::touchDragExitAction), CCControlEventTouchDragExit);        controlButton->addTargetWithActionForControlEvents(this, cccontrol_selector(CCControlButtonTest_Event::touchUpInsideAction), CCControlEventTouchUpInside);        controlButton->addTargetWithActionForControlEvents(this, cccontrol_selector(CCControlButtonTest_Event::touchUpOutsideAction), CCControlEventTouchUpOutside);        controlButton->addTargetWithActionForControlEvents(this, cccontrol_selector(CCControlButtonTest_Event::touchCancelAction), CCControlEventTouchCancel);        bRet = true;    } while (0);return bRet;}

触发事件代码和层的创建添加就不多写了……

再来看看Slider滑动条,这个应用也是很普遍的,什么设置音量,显示参数之类的……其实它的用法和平常用的差不多,下面是代码:

//添加一个滑动条class CCControlSliderTest : public cocos2d::CCLayer{public:    bool init();    //这个就是滑动时的事件了    void valueChanged(CCObject *sender, CCControlEvent controlEvent);    cocos2d::CCLabelTTF* m_pDisplayValueLabel;    CREATE_FUNC(CCControlSliderTest)};

//这里代码照抄bool CCControlSliderTest::init(){bool bRet = false;    do     {        //////////////////////////////////////////////////////////////////////////        // super init first        //////////////////////////////////////////////////////////////////////////        CC_BREAK_IF(! CCLayer::init());        CCSize screenSize = CCDirector::sharedDirector()->getWinSize();        // Add a label in which the slider value will be displayed        m_pDisplayValueLabel = CCLabelTTF::create("Move the slider thumb!\nThe lower slider is restricted." ,"Marker Felt", 18);        m_pDisplayValueLabel->retain();        m_pDisplayValueLabel->setAnchorPoint(ccp(0.5f, -1.0f));        m_pDisplayValueLabel->setPosition(ccp(screenSize.width / 1.7f, screenSize.height / 2.0f));        addChild(m_pDisplayValueLabel);        // Add the slider,这里的三张图片分别对应于滑动条的三个部分        CCControlSlider *slider = CCControlSlider::create("sliderTrack.png","sliderProgress.png" ,"sliderThumb.png");        slider->setAnchorPoint(ccp(0.5f, 1.0f));        //设定最大最小值        slider->setMinimumValue(0.0f); // Sets the min value of range        slider->setMaximumValue(5.0f); // Sets the max value of range        slider->setPosition(ccp(screenSize.width / 2.0f, screenSize.height / 2.0f + 16));        //给控件加个标识号作索引用slider->setTag(1);        // When the value of the slider will change, the given selector will be call        //这里和按钮一样,绑定一个拖动后的触发事件        slider->addTargetWithActionForControlEvents(this, cccontrol_selector(CCControlSliderTest::valueChanged), CCControlEventValueChanged);CCControlSlider *restrictSlider = CCControlSlider::create("sliderTrack.png","sliderProgress.png" ,"sliderThumb.png");        restrictSlider->setAnchorPoint(ccp(0.5f, 1.0f));        restrictSlider->setMinimumValue(0.0f); // Sets the min value of range        restrictSlider->setMaximumValue(5.0f); // Sets the max value of range        //这里设置的是允许的最大、最小拖动值,也就是说最大值只能拖到4……restrictSlider->setMaximumAllowedValue(4.0f);restrictSlider->setMinimumAllowedValue(1.5f);restrictSlider->setValue(3.0f);        restrictSlider->setPosition(ccp(screenSize.width / 2.0f, screenSize.height / 2.0f - 24));       restrictSlider->setTag(2);//same with restrictedrestrictSlider->addTargetWithActionForControlEvents(this, cccontrol_selector(CCControlSliderTest::valueChanged), CCControlEventValueChanged);        addChild(slider);    addChild(restrictSlider);        bRet = true;    } while (0);return bRet;}void CCControlSliderTest::valueChanged(CCObject *sender, CCControlEvent controlEvent){    CCControlSlider* pSlider = (CCControlSlider*)sender;    // Change value of label.这里根据索引来显示当前拖动的滑动条的数值if(pSlider->getTag() == 1)m_pDisplayValueLabel->setString(CCString::createWithFormat("Upper slider value = %.02f", pSlider->getValue())->getCString());  if(pSlider->getTag() == 2)m_pDisplayValueLabel->setString(CCString::createWithFormat("Lower slider value = %.02f", pSlider->getValue())->getCString()); }

继续->开关按钮,代码:

class CCControlSwitchTest : public cocos2d::CCLayer{public:    bool init();    /** Callback for the change value. */    void valueChanged(CCObject* sender, CCControlEvent controlEvent);    CCLabelTTF *m_pDisplayValueLabel;    CREATE_FUNC(CCControlSwitchTest)};

//开关按钮bool CCControlSwitchTest::init(){bool bRet = false;    do     {        //////////////////////////////////////////////////////////////////////////        // super init first        //////////////////////////////////////////////////////////////////////////        CC_BREAK_IF(! CCLayer::init());        CCSize screenSize = CCDirector::sharedDirector()->getWinSize();        CCNode *layer = CCNode::create();        layer->setPosition(ccp (screenSize.width / 2-120, screenSize.height / 2+100));//这里又多加了一个子层用来显示开关按钮的状态        addChild(layer, 1);                double layer_width = 0;                // Add the black background for the text        CCScale9Sprite *background = CCScale9Sprite::create("buttonBackground.png");        background->setContentSize(CCSizeMake(80, 50));        background->setPosition(ccp(layer_width + background->getContentSize().width / 2.0f, 0));        layer->addChild(background);                layer_width += background->getContentSize().width;                m_pDisplayValueLabel  = CCLabelTTF::create("#color" ,"Marker Felt" ,30);        m_pDisplayValueLabel->retain();        m_pDisplayValueLabel->setPosition(background->getPosition());        layer->addChild(m_pDisplayValueLabel);                // Create the switch这里需要四平张图片来显示控件各部分//创建方式还有另一种,就是不加标签显示,去掉最后两个参数即是        CCControlSwitch *switchControl = CCControlSwitch::create            (                CCSprite::create("switch-mask.png"),                CCSprite::create("switch-on.png"),                CCSprite::create("switch-off.png"),                CCSprite::create("switch-thumb.png"),                CCLabelTTF::create("On", "Arial-BoldMT", 16),                CCLabelTTF::create("Off", "Arial-BoldMT", 16)            );        switchControl->setPosition(ccp (layer_width + 10 + switchControl->getContentSize().width / 2, 0));        layer->addChild(switchControl);       //绑定事件        switchControl->addTargetWithActionForControlEvents(this, cccontrol_selector(CCControlSwitchTest::valueChanged), CCControlEventValueChanged);                // Set the layer size        layer->setContentSize(CCSizeMake(layer_width, 0));        layer->setAnchorPoint(ccp (0.5f, 0.5f));                // Update the value label和button一样,它也有很多状态参数,这里便是指定在值产生变化的时候执行valueChanged中的代码        valueChanged(switchControl, CCControlEventValueChanged);        bRet = true;    } while (0);return bRet;}void CCControlSwitchTest::valueChanged(CCObject* sender, CCControlEvent controlEvent){//拿到操作对象    CCControlSwitch* pSwitch = (CCControlSwitch*)sender;//根据按钮当前的状态显示标签内容    if (pSwitch->isOn())    {        m_pDisplayValueLabel->setString("On");    }     else    {        m_pDisplayValueLabel->setString("Off");    }}

继续->步进器,这个东西也是很常用的,常用用于参数微调,看代码:

//步进器class CCControlStepperTest : public cocos2d::CCLayer{public:    bool init();    // Creates and returns a new ControlStepper. cocos2d::extension::CCControlStepper* makeControlStepper();virtual void onExit();    // Callback for the change value.     void valueChanged(CCObject *sender, CCControlEvent controlEvent);protected:// 在setDisplayValueLabel的时候,调用原有m_pDisplayValueLabel的release,并且调用新值的的retain,专用于声明protected的变量//具体请进源码里参考对此宏的定义    CC_SYNTHESIZE_RETAIN(cocos2d::CCLabelTTF*, m_pDisplayValueLabel, DisplayValueLabel)    CREATE_FUNC(CCControlStepperTest)};

//添加一个步进器bool CCControlStepperTest::init(){bool bRet = false;    do     {        //////////////////////////////////////////////////////////////////////////        // super init first        //////////////////////////////////////////////////////////////////////////        CC_BREAK_IF(! CCLayer::init());//初始化    m_pDisplayValueLabel=NULL;        CCSize screenSize = CCDirector::sharedDirector()->getWinSize();                CCNode *layer = CCNode::create();        layer->setPosition(ccp (screenSize.width / 2+100, screenSize.height / 2+100));        this->addChild(layer, 1);                double layer_width          = 0;                // Add the black background for the text        CCScale9Sprite *background  = CCScale9Sprite::create("buttonBackground.png");        background->setContentSize(CCSizeMake(100, 50));        background->setPosition(ccp(layer_width + background->getContentSize().width / 2.0f, 0));        layer->addChild(background);        //使用setter创建一个用于显示当前值的label        this->setDisplayValueLabel(CCLabelTTF::create("0", "HelveticaNeue-Bold", 30));        m_pDisplayValueLabel->setPosition(background->getPosition());        layer->addChild(m_pDisplayValueLabel);                layer_width  += background->getContentSize().width;        //调用创建        CCControlStepper *stepper   = this->makeControlStepper();        stepper->setPosition(ccp (layer_width + 10 + stepper->getContentSize().width / 2, 0));        stepper->addTargetWithActionForControlEvents(this, cccontrol_selector(CCControlStepperTest::valueChanged), CCControlEventValueChanged);        layer->addChild(stepper);                layer_width                 += stepper->getContentSize().width;                // Set the layer size        layer->setContentSize(CCSizeMake(layer_width, 0));        layer->setAnchorPoint(ccp (0.5f, 0.5f));                // Update the value label        this->valueChanged(stepper, CCControlEventValueChanged);bRet = true;    } while (0);return bRet;}//这里把创建步进器的过程独立出来了CCControlStepper *CCControlStepperTest::makeControlStepper(){    CCSprite *minusSprite       = CCSprite::create("stepper-minus.png");    CCSprite *plusSprite        = CCSprite::create("stepper-plus.png");        return CCControlStepper::create(minusSprite, plusSprite);}void CCControlStepperTest::valueChanged(CCObject *sender, CCControlEvent controlEvent){    CCControlStepper* pControl = (CCControlStepper*)sender;    // Change value of label.    m_pDisplayValueLabel->setString(CCString::createWithFormat("%0.02f", (float)pControl->getValue())->getCString());}void CCControlStepperTest::onExit(){CC_SAFE_RELEASE(m_pDisplayValueLabel);}

看了下源码中还定义有一对宏:

CC_SYNTHESIZE_RETAIN(CCSprite*, m_pMinusSprite, MinusSprite)CC_SYNTHESIZE_RETAIN(CCSprite*, m_pPlusSprite, PlusSprite)
用这个的话应该就能用来操控自定义的精灵属性了(貌似很有用^_^)……,人懒啊……所以就不测试了……

官方原例中还有个很酷的电位计按钮,其实使用和步进器是一样的,就不写了。另还有颜色拾取器也自己去看吧,估计我很难用到这东西……

还是推荐一篇文章,应该多看看cocos2d-x的内存管理(我总是自以为是的释放然后报错是……):http://blog.csdn.net/honghaier/article/details/8160519 

下面是源代码下载:http://download.csdn.net/detail/cyistudio/5459721


原创粉丝点击