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