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 restricted restrictSlider->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