cocos2dx之event事件(二):事件监听器EventListener

当需要响应事件时,就需要用到EventListener. EventListener的核心作用是存储发生Event时的回调函数,通过属性_fixedPriority判断回调执行先后顺序.所有的EventListener都存储于EventDispatcher中,关于EventDispatcher的部分请看下篇分析.

class CC_DLL EventListener : public Ref
{
public:
	enum class Type
	{
		UNKNOWN,
		TOUCH_ONE_BY_ONE,
		TOUCH_ALL_AT_ONCE,
		KEYBOARD,
		MOUSE,
		ACCELERATION,
		FOCUS,
		GAME_CONTROLLER,
		CUSTOM
	};
	//已省略成员函数,只看属性
	typedef std::string ListenerID;
	std::function _onEvent;// 回调函数,通常为NULL, 回调函数通常保存在子类中
	Type _type;// 监听器类型,和Event一一对应,唯有TOUCH类型被分为单点触摸TOUCH_ONE_BY_ONE和多点触摸TOUCH_ALL_AT_ONCE
	ListenerID _listenerID;// Event listener ID,在子类中为static,一类listenerID一样,比如单点触摸类的ID为__cc_touch_one_by_one
	bool _isRegistered;// 判断是否已加入事件分发器EventDispatcher
	int   _fixedPriority;// 优先级,该值越低的listener越先接到事件,根据优先级的数值listener分为两类:
// 优先级为0的为SceneGraphListener,非0为fixedListener
	Node* _node;// SceneGraphListener类listener分发事件时参考的node
	bool _paused;// 是否暂停,正常监听的listener为true,仅对SceneGraphListener有效
	bool _isEnabled;// 是否激活,正常监听的listener为true
	friend class EventDispatcher;
};

以上是EventListener的源码,属性的作用在注释中说明.

当需要响应事件的时候,何时需要创建EventListener并加入到EventDispatcher中,何时只需要设置回调函数?是个需要考虑的问题
Widget,Layer,ScrollView 3个类自带单点触摸监听器 EventListenerTouchOneByOne* _touchListener,如果使用这3个类和他们的子类(比如Button,CheckBox)来响应单点触摸的时候,则不需要创建EventListener,其他情况需要创建EventListener.

Listener创建好之后,应该以FixedPriority还是以SceneGraphPriority加入EventDispatcher中,是接下来要考虑的.

一个简单的方法是,如果该listener需要按遮挡先后顺序来响应触摸的话就用SceneGraphPriority,否则就用FixedPriority

需要注意的是,listener的子类对于感受到的事件情况进行了细分. 举例来说,键盘事件有键按下和键弹起两种情况,最常用的触摸事件有触摸开始(开始接触),触摸移动(接触后滑动),触摸结束(接触后分开,终点落在控件内),触摸取消(接触后分开,终点落在控件外)4种情况,并设置了这4个细分事件的回调函数.当需要控件细致的区分这4种情况时,调用addTouchEventListener.例如:

void HelloWorld::touchCB(Ref* ref, Widget::TouchEventType type);
pBtn->addTouchEventListener(CC_CALLBACK_2(HelloWorld::touchCB, this));

当只需要响应触摸结束时,使用addClickEventListener.例如:

void HelloWorld::clickCB(Ref* ref);
pBtn->addClickEventListener(CC_CALLBACK_1(HelloWorld::clickCB, this));




你可能感兴趣的:(cocos2dx)