【唠叨】

    开关类CCControlSwitch继承于控件类CCControl。

    控件类CCControl主要向子类提供了一系列的控件触发事件。当子控件触发相关的事件后,就会执行相关的控件事件回调函数。这与之前讲的CCMenu中的菜单按钮回调是类似的。

    控件类CCControl主要有三个子类:

        (1)开关控件CCControlSwitch 

        (2)滑块控件CCControlSlider 

        (3)按钮控件CCControlButton 

    本节讲的是其子类其中之一:开关类CCControlSwitch


【Demo下载】

    https://github.com/shahdza/Cocos_LearningTest/tree/master/demo_%E5%BC%80%E5%85%B3%E6%8C%89%E9%92%AECCControlSwitch 


【3.x】

    (1)去掉 “CC”

    (2)对象类 CCObject 改为 Ref

    (3)标签类 LabelTTF 改为 Label

    (4)CCControlEvent 改为强枚举 Control::EventType

    (5)CCControlEventValueChanged 改为 Control::EventType::VALUE_CHANGED

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


    (7)关于创建函数create,必须引起注意!

        > 这是3.x的一个BUG。

//
	//v3.x会报错,必须指定onLabel、offLabel。不能为nullptr
	create(Sprite* maskSprite, Sprite* onSprite, Sprite* offSprite, Sprite* thumbSprite);

	//v3.x版本中,必须使用这个来创建
	create(Sprite* maskSprite, Sprite* onSprite, Sprite* offSprite, Sprite* thumbSprite, Label* onLabel, Label* offLabel);
//

    

    (9)其他地方几乎无变化。




【CCControlSwitch】

    开关控件CCControlSwitch,应该也是很常见的UI控件,想必大家都不陌生。比如声音开关的控制,一些功能的启用与禁用都需要用到开关控件。

wKioL1P0FYLieGeXAAAM1b7lElU964.jpg        wKioL1P0FYKD6dYyAAAM0MG8Hoo275.jpg


1、CCControl主要向开关类CCControlSwitch提供了以下控件事件

//
	CCControlEventValueChanged  //当控件的值发生改变时触发。
//


2、绑定控件事件的方法

//
	//绑定控件事件
	//addTargetWithActionForControlEvents(this, cccontrol_selector(HelloWorld::valueChanged), CCControlEventValueChanged);
	void addTargetWithActionForControlEvents(CCObject* target, SEL_CCControlHandler action, CCControlEvent controlEvents);

	//删除控件事件
	//removeTargetWithActionForControlEvents(this, cccontrol_selector(HelloWorld::valueChanged), CCControlEventValueChanged);
	void removeTargetWithActionForControlEvents(CCObject* target, SEL_CCControlHandler action, CCControlEvent controlEvents);
//


3、需要引用以下头文件及命名空间

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


4、常用操作

//
class CCControlSwitch : public CCControl
{
/**
 *		创建CCControlSwitch的两种方式
 */
	//CCControlSwitch::create("底图","打开状态图","关闭状态图","拨动开关图");
	//v3.x会报错,必须指定onLabel、offLabel
	static CCControlSwitch* create(CCSprite *maskSprite, CCSprite * onSprite, CCSprite * offSprite, CCSprite * thumbSprite);

	//CCControlSwitch::create("底图","打开状态图","关闭状态图","拨动开关图","打开状态文字","关闭状态文字");
	static CCControlSwitch* create(CCSprite *maskSprite, CCSprite * onSprite, CCSprite * offSprite, CCSprite * thumbSprite, CCLabelTTF* onLabel, CCLabelTTF* offLabel);


/**
 *		设置开关状态
 *		setOn , isOn , hasMoved , setEnabled
 */
	void setOn(bool isOn);                 //设置开关状态
	void setOn(bool isOn, bool animated);  //设置开关状态
	bool isOn(void) { return m_bOn; }      //获取开关状态
	bool hasMoved() { return m_bMoved; }   //获取当前开关是否为手动拨动开关(区别于点击拨动)
	virtual void setEnabled(bool enabled); //设置开关是否能操作

};
//




【代码实战】


1、资源图片

    第一组开关:

            wKiom1P0MCyg6hNRAAAIVsOjSXw121.jpg wKioL1P0MUTyG8_dAAAJNWEietA461.jpg wKiom1P0MCzD0XFvAAAKB2gwnSA847.jpg wKioL1P0MUTxcllsAAAKY7buzoQ201.jpg

    第二组开关:

            wKiom1P0MCzBH_mQAAAGr5GqgV0972.jpg wKioL1P0MUWC0HrjAAAIVCIAGqA976.jpg wKiom1P0MC2DYcSSAAAHfaCk6Go492.jpg  wKioL1P0MUXTtF_vAAAHfcOt5ls381.jpg



2、引入文件和命名空间

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


3、在HelloWorld.h中声明控件回调函数、显示开关的状态Label

//
	CCLabelTTF* label;  //用于显示开关控件的状态ON/OFF

	void valueChanged(CCObject* sender, CCControlEvent controlEvent); //当值改变时触发的控件事件
//


4、在HelloWorld.cpp中分别创建两种方式的开关控件

//
//第一组开关
	CCSprite* bg1 = CCSprite::create("ControlSwith_bg.png");
	CCSprite* on1 = CCSprite::create("ControlSwith_on.png");
	CCSprite* off1 = CCSprite::create("ControlSwith_off.png");
	CCSprite* thumb1 = CCSprite::create("ControlSwith_thumb.png");
	CCControlSwitch* controlSwitch1 = CCControlSwitch::create(bg1, on1, off1, thumb1);
	controlSwitch1->setPosition( midPos - ccp(100, 100) );
	this->addChild(controlSwitch1);

	//绑定事件,当开关控件的值发生改变时触发事件。
	controlSwitch1->addTargetWithActionForControlEvents(this, cccontrol_selector(HelloWorld::valueChanged), CCControlEventValueChanged);


//第二组开关
	CCSprite* bg2 = CCSprite::create("switch-mask.png");
	CCSprite* on2 = CCSprite::create("switch-off.png");
	CCSprite* off2 = CCSprite::create("switch-on.png");
	CCSprite* thumb2 = CCSprite::create("switch-thumb.png");
	CCLabelTTF* TTFon = CCLabelTTF::create("on", "Arial", 20);
	CCLabelTTF* TTFoff = CCLabelTTF::create("off", "Arial", 20);
	CCControlSwitch* controlSwitch2 = CCControlSwitch::create(bg2, on2, off2, thumb2, TTFon, TTFoff);
	controlSwitch2->setPosition( midPos - ccp(-100, 100) );
	this->addChild(controlSwitch2);
//


5、实现控件回调函数

//
	//事件响应函数,值改变时,修改label标签的内容
	void HelloWorld::valueChanged(CCObject* sender, CCControlEvent controlEvent)
	{
	//获取事件的传递者CCControlSwitch
		CCControlSwitch* controlSwitch = (CCControlSwitch*)sender;
		
	//根据开关控件的状态,设置label标签的内容
		if( controlSwitch->isOn() ) 
		{
			label->setString("ON");
		}
		else 
		{
			label->setString("OFF");
		}
	}
//


6、运行结果

cocos2dx基础篇(10)——开关按钮CCControlSwitch_第1张图片


7、分析与总结

    (1)是不是感觉第一组的按钮有点奇怪?开关和底图没有完全覆盖,另外开状态的图片和关状态的图片也没有完全消失。呵呵t_0004.gif

    (2)第二组开关按钮的效果比较好,所以你应该明白为啥我选了两组不同的图片来创建两种开关控件了吧?