#ifndef __CC_touch_H__#define __CC_touch_H__#include "base/CCRef.h"#include "math/CCGeometry.h"NS_CC_BEGIN/** @class touch * @brIEf Encapsulates the touch information,such as touch point,ID and so on,and provIDes the methods that commonly used. */class CC_DLL touch : public Ref{public: /** * dispatch mode,how the touches are dispathced. * @Js NA */ enum class dispatchMode { ALL_AT_ONCE,/** All at once. */ ONE_BY_ONE,/** One by one. */ }; // 构造函数.cocos2dx源码中 voID GLVIEw::handletouchesBegin(int num,intptr_t IDs[],float xs[],float ys[])调用过。 touch() : _ID(0),_startPointCaptured(false) { } /** Set the touch infomation. It always used to monitor touch event. * * @param ID A given ID * @param x A given x coordinate. * @param y A given y coordinate. */ voID settouchInfo(int ID,float x,float y) { _ID = ID; _prevPoint = _point; _point.x = x; _point.y = y; if (!_startPointCaptured) // 首次设置touchInfo,startPoint、prevPoint 与 point相等。 { _startPoint = _point; _startPointCaptured = true; _prevPoint = _point; } } // in openGL coordinates. (开始坐标,前一个坐标,当前坐标) Vec2 getStartLocation() const; Vec2 getPrevIoUsLocation() const; Vec2 getLocation() const; // in screen coordinates. (开始坐标,前一个坐标,当前坐标) Vec2 getStartLocationInVIEw() const; Vec2 getPrevIoUsLocationInVIEw() const; Vec2 getLocationInVIEw() const; // 当前坐标和前一个坐标之间的差值。 Vec2 getDelta() const; /** Get touch ID. * @Js getID * @lua getID * * @return The ID of touch. */ int getID() const { return _ID; }private: int _ID; // ID bool _startPointCaptured; // 是否捕获过开始点 Vec2 _startPoint; // 开始点 Vec2 _point; // 当前点 Vec2 _prevPoint; // 上一次点坐标};NS_CC_END#endif
#include "base/CCtouch.h"#include "base/CCDirector.h"NS_CC_BEGIN// returns the current touch location in screen coordinatesVec2 touch::getLocationInVIEw() const { return _point; }// returns the prevIoUs touch location in screen coordinatesVec2 touch::getPrevIoUsLocationInVIEw() const { return _prevPoint; }// returns the start touch location in screen coordinatesVec2 touch::getStartLocationInVIEw() const { return _startPoint; }// returns the current touch location in OpenGL coordinatesVec2 touch::getLocation() const{ return Director::getInstance()->convertToGL(_point); }// returns the prevIoUs touch location in OpenGL coordinatesVec2 touch::getPrevIoUsLocation() const{ return Director::getInstance()->convertToGL(_prevPoint); }// returns the start touch location in OpenGL coordinatesVec2 touch::getStartLocation() const{ return Director::getInstance()->convertToGL(_startPoint); }// returns the delta position between the current location and the prevIoUs location in OpenGL coordinatesVec2 touch::getDelta() const{ return getLocation() - getPrevIoUsLocation();}NS_CC_END
touch类相对比较简单。
待解决问题:
1.touch对象在CCGLvIEw的创建,以及整个流程。
2.Director::getInstance()->convertToGL(_point); 坐标转换问题。
#ifndef __CCEVENT_H__#define __CCEVENT_H__#include "base/CCRef.h"#include "platform/CCPlatformMacros.h"NS_CC_BEGINclass Node;// 所有事件的基类class CC_DLL Event : public Ref{public: // 内部枚举类Type(使用方法,Event::Type::touch) enum class Type { touch,KEYBOARD,acceleration,MOUSE,FOCUS,GAME_CONTRolLER,CUSTOM }; public: Event(Type type); virtual ~Event(); // 类型 inline Type getType() const { return _type; }; // 停止传播事件 inline voID stopPropagation() { _isstopped = true; }; // 事件是否停止 inline bool isstopped() const { return _isstopped; }; // 与node关联的事件才有用,fixedPriority 返回0.(It onlys be available when the event Listener is associated with node. It returns 0 when the Listener is associated with fixed priority.) inline Node* getCurrentTarget() { return _currentTarget; }; protected: inline voID setCurrentTarget(Node* target) { _currentTarget = target; }; Type _type; // 描述当前对象的事件类型。 bool _isstopped; // 描述当前事件是否已经停止。 Node* _currentTarget; // 是侦听事件的Node类型的对象。 frIEnd class Eventdispatcher;};NS_CC_END#endif
#include "base/CCEvent.h"NS_CC_BEGINEvent::Event(Type type): _type(type),_isstopped(false),_currentTarget(nullptr){}Event::~Event(){}NS_CC_ENDEvent类是事件类的基类,有3个重要属性:
1.target
2.type
3.isstopped
#ifndef __cocos2d_libs__touchEvent__#define __cocos2d_libs__touchEvent__#include "base/CCEvent.h"#include <vector>NS_CC_BEGINclass touch;#define touch_PERF_DEBUG 1class CC_DLL Eventtouch : public Event{public: static const int MAX_touches = 15; // 事件的最大touch个数。 // 内部枚举类EventCode。在dispatcher event时会用到。 enum class EventCode { BEGAN,MOVED,ENDED,CANCELLED }; Eventtouch(); inline EventCode getEventCode() const { return _eventCode; }; // 当前触摸屏幕所有点的列表 inline const std::vector<touch*>& gettouches() const { return _touches; }; // 测试相关方法#if touch_PERF_DEBUG voID setEventCode(EventCode eventCode) { _eventCode = eventCode; }; voID settouches(const std::vector<touch*>& touches) { _touches = touches; };#endif private: EventCode _eventCode; // 事件code(began,moved,ended,cancelled) std::vector<touch*> _touches; // touch数组 获取当前触摸屏幕所有点的列表 frIEnd class GLVIEw;};NS_CC_END#endif
#include "base/CCEventtouch.h"#include "base/CCtouch.h"NS_CC_BEGINEventtouch::Eventtouch(): Event(Type::touch){ _touches.reserve(MAX_touches);}NS_CC_ENDEventtouch类继承自Event,加上Event的3个属性,Eventtouch共有5个属性:
1.target
2.type
3.isstopped
4.touches:当前触摸屏幕所有点的列表
5.eventCode:该属性在dispatcher中会用到,后面分析。
#ifndef __cocos2d_libs__CCCustomEvent__#define __cocos2d_libs__CCCustomEvent__#include <string>#include "base/CCEvent.h"NS_CC_BEGINclass CC_DLL EventCustom : public Event{public: EventCustom(const std::string& eventname); inline voID setUserData(voID* data) { _userData = data; }; inline voID* getUserData() const { return _userData; }; inline const std::string& getEventname() const { return _eventname; };protected: voID* _userData; // User data std::string _eventname;};NS_CC_END#endif
#include "base/CCEventCustom.h"#include "base/CCEvent.h"NS_CC_BEGINEventCustom::EventCustom(const std::string& eventname): Event(Type::CUSTOM),_userData(nullptr),_eventname(eventname){}NS_CC_END
EventCustom类继承自Event,加上Event的3个属性,EventCustom共有5个属性:
1.target
2.type
3.isstopped
4.eventname
5.userData
使用EventCustom的地方还是很多的,这里只粗略介绍下。
#ifndef __CCEVENTListENER_H__#define __CCEVENTListENER_H__#include <functional>#include <string>#include <memory>#include "platform/CCPlatformMacros.h"#include "base/CCRef.h"NS_CC_BEGINclass Event;class Node;/** @class EventListener * @brIEf The base class of event Listener. * If you need custom Listener which with different callback,you need to inherit this class. * For instance,you Could refer to EventListeneracceleration,EventListenerKeyboard,EventListenertouchOneByOne,EventListenerCustom. */class CC_DLL EventListener : public Ref{public: /** Type Event type.*/ // 这个类型与Event的类型有一小点不同,就是将触摸事件类型分成了 One by One (一个接一个) 与 All At Once (同时一起)两种。 enum class Type { UNKNowN,touch_ONE_BY_ONE,touch_ALL_AT_ONCE,CUSTOM }; typedef std::string ListenerID; public: EventListener(); bool init(Type t,const ListenerID& ListenerID,const std::function<voID(Event*)>& callback); virtual ~EventListener(); // 纯虚函数监测监听器是否可用 virtual bool checkAvailable() = 0; // 纯虚函数,因为clone的方式不同,又需要这个功能接口,所以在设置为纯虚函数,使子类必需实现。 virtual EventListener* clone() = 0; // 当EventListener enabled并且not paused时,EventListener才能接受事件。 inline voID setEnabled(bool enabled) { _isEnabled = enabled; }; inline bool isEnabled() const { return _isEnabled; };protected: /** Gets the type of this Listener * @note It's different from `EventType`,e.g. touchEvent has two kinds of event Listeners - EventListenerOneByOne,EventListenerAllAtOnce */ inline Type getType() const { return _type; }; // eventType && ListenerID ===> Listeners. EventListenertouchOneByOne::ListENER_ID = "__cc_touch_one_by_one"; EventListenertouchAllAtOnce::ListENER_ID = "__cc_touch_all_at_once"; (When event is being dispatched,Listener ID is used as key for searching Listeners according to event type.) inline const ListenerID& getListenerID() const { return _ListenerID; }; // 注册 inline voID setRegistered(bool registered) { _isRegistered = registered; }; inline bool isRegistered() const { return _isRegistered; }; /************************************************ Sets paused state for the Listener The paused state is only used for scene graph priority Listeners. `Eventdispatcher::resumeAllEventListenersForTarget(node)` will set the paused state to `false`,while `Eventdispatcher::pauseAllEventListenersForTarget(node)` will set it to `true`. @note 1) Fixed priority Listeners will never get paused. If a fixed priority doesn't want to receive events,call `setEnabled(false)` instead. 2) In `Node`'s onEnter and onExit,the `paused state` of the Listeners which associated with that node will be automatically updated. sceneGraPHPriorityListener: fixedPriorityListener:不使用_paused属性。 paused状态在node 的“onEnter”和“onExit”中改变 ************************************************/ inline voID setPaused(bool paused) { _paused = paused; }; inline bool isPaused() const { return _paused; }; // 获取与Listener相关联的node。fixed priority Listeners为nullptr。 inline Node* getAssociatednode() const { return _node; }; inline voID setAssociatednode(Node* node) { _node = node; }; // 用于fixed priority Listeners,可以设为不为0的值。 inline voID setFixedPriority(int fixedPriority) { _fixedPriority = fixedPriority; }; inline int getFixedPriority() const { return _fixedPriority; }; protected: Type _type; // Event Listener type ListenerID _ListenerID; // Event Listener ID std::function<voID(Event*)> _onEvent; // Event callback function bool _isRegistered; // Whether the Listener has been added to dispatcher. bool _isEnabled; // Whether the Listener is enabled bool _paused; // Whether the Listener is paused Node* _node; // scene graph based priority int _fixedPriority; // The higher the number,the higher the priority,0 is for scene graph base priority. frIEnd class Eventdispatcher;};NS_CC_END#endif
#include "base/CCEventListener.h"NS_CC_BEGINEventListener::EventListener(){} EventListener::~EventListener() { cclOGINFO("In the destructor of EventListener. %p",this);}bool EventListener::init(Type t,const std::function<voID(Event*)>& callback){ _onEvent = callback; _type = t; _ListenerID = ListenerID; _isRegistered = false; _paused = true; _isEnabled = true; return true;}bool EventListener::checkAvailable(){ return (_onEvent != nullptr);}NS_CC_ENDEventListener是事件监听器的基类,有8个属性:
1.type
2.ListenerID
3.onEvent
4.register
5.paused
6.enabled
7.node
8.fixedPriority
#ifndef __cocos2d_libs__CCtouchEventListener__#define __cocos2d_libs__CCtouchEventListener__#include "base/CCEventListener.h"#include <vector>NS_CC_BEGINclass touch;// 单点触摸监听器class CC_DLL EventListenertouchOneByOne : public EventListener{public: static const std::string ListENER_ID; // 创建单点触摸事件监听器 static EventListenertouchOneByOne* create(); EventListenertouchOneByOne(); bool init(); virtual ~EventListenertouchOneByOne(); // 是否吞噬掉触摸点,如果true,触摸将不会向下层传播。 bool isSwallowtouches(); voID setSwallowtouches(bool needSwallow); /// OverrIDes 重写夫类的纯虚函数。 virtual EventListenertouchOneByOne* clone() overrIDe; virtual bool checkAvailable() overrIDe; public:// typedef std::function<bool(touch*,Event*)> cctouchBeganCallback;// typedef std::function<voID(touch*,Event*)> cctouchCallback; // public方法:创建监听器时,需手动设置 ontouch方法(ontouchBegan,ontouchmoved,ontouchended,ontouchCancelled)。 std::function<bool(touch*,Event*)> ontouchBegan; std::function<voID(touch*,Event*)> ontouchmoved; std::function<voID(touch*,Event*)> ontouchended; std::function<voID(touch*,Event*)> ontouchCancelled; private: std::vector<touch*> _claimedtouches; // 触摸点列表。(ontouchBegan 返回true)&&(Listener已经注册)过的touch对象才会被添加。 bool _needSwallow; // 是否需要吞噬触摸点 frIEnd class Eventdispatcher;};// 多点触摸监听器class CC_DLL EventListenertouchAllAtOnce : public EventListener{public: static const std::string ListENER_ID; static EventListenertouchAllAtOnce* create(); EventListenertouchAllAtOnce(); bool init(); virtual ~EventListenertouchAllAtOnce(); /// OverrIDes virtual EventListenertouchAllAtOnce* clone() overrIDe; virtual bool checkAvailable() overrIDe;public: typedef std::function<voID(const std::vector<touch*>&,Event*)> cctouchesCallback; cctouchesCallback ontouchesBegan; cctouchesCallback ontouchesMoved; cctouchesCallback ontouchesEnded; cctouchesCallback ontouchesCancelled; private: frIEnd class Eventdispatcher;};NS_CC_END#endif
#include "base/CCEventListenertouch.h"#include "base/CCEventdispatcher.h"#include "base/CCEventtouch.h"#include "base/CCtouch.h"#include <algorithm>NS_CC_BEGINconst std::string EventListenertouchOneByOne::ListENER_ID = "__cc_touch_one_by_one";EventListenertouchOneByOne* EventListenertouchOneByOne::create(){ auto ret = new (std::nothrow) EventListenertouchOneByOne(); if (ret && ret->init()) { ret->autorelease(); } else { CC_SAFE_DELETE(ret); } return ret;}EventListenertouchOneByOne::EventListenertouchOneByOne(): ontouchBegan(nullptr),ontouchmoved(nullptr),ontouchended(nullptr),ontouchCancelled(nullptr),_needSwallow(false){}bool EventListenertouchOneByOne::init(){ if (EventListener::init(Type::touch_ONE_BY_ONE,ListENER_ID,nullptr)) { return true; } return false;}EventListenertouchOneByOne::~EventListenertouchOneByOne(){ cclOGINFO("In the destructor of EventListenertouchOneByOne,%p",this);}voID EventListenertouchOneByOne::setSwallowtouches(bool needSwallow){ _needSwallow = needSwallow;}bool EventListenertouchOneByOne::isSwallowtouches(){ return _needSwallow;}bool EventListenertouchOneByOne::checkAvailable(){ // Eventdispatcher will use the return value of 'ontouchBegan' to determine whether to pass following 'move','end' // message to 'EventListenertouchOneByOne' or not. So 'ontouchBegan' needs to be set. // ontouchBegin 必须需要。 if (ontouchBegan == nullptr) { CCASSERT(false,"InvalID EventListenertouchOneByOne!"); return false; } return true;}EventListenertouchOneByOne* EventListenertouchOneByOne::clone(){ auto ret = new (std::nothrow) EventListenertouchOneByOne(); if (ret && ret->init()) { ret->autorelease(); ret->ontouchBegan = ontouchBegan; ret->ontouchmoved = ontouchmoved; ret->ontouchended = ontouchended; ret->ontouchCancelled = ontouchCancelled; ret->_claimedtouches = _claimedtouches; ret->_needSwallow = _needSwallow; } else { CC_SAFE_DELETE(ret); } return ret;}/////////const std::string EventListenertouchAllAtOnce::ListENER_ID = "__cc_touch_all_at_once";EventListenertouchAllAtOnce::EventListenertouchAllAtOnce(): ontouchesBegan(nullptr),ontouchesMoved(nullptr),ontouchesEnded(nullptr),ontouchesCancelled(nullptr){}EventListenertouchAllAtOnce::~EventListenertouchAllAtOnce(){ cclOGINFO("In the destructor of EventListenertouchAllAtOnce,this);}bool EventListenertouchAllAtOnce::init(){ if (EventListener::init(Type::touch_ALL_AT_ONCE,nullptr)) { return true; } return false;}EventListenertouchAllAtOnce* EventListenertouchAllAtOnce::create(){ auto ret = new (std::nothrow) EventListenertouchAllAtOnce(); if (ret && ret->init()) { ret->autorelease(); } else { CC_SAFE_DELETE(ret); } return ret;}bool EventListenertouchAllAtOnce::checkAvailable(){ // ontouchesBegin、ontouchesMoved、ontouchesEnded、ontouchesCancelled 只需要任意一个不为空就行了 if (ontouchesBegan == nullptr && ontouchesMoved == nullptr&& ontouchesEnded == nullptr && ontouchesCancelled == nullptr) { CCASSERT(false,"InvalID EventListenertouchAllAtOnce!"); return false; } return true;}EventListenertouchAllAtOnce* EventListenertouchAllAtOnce::clone(){ auto ret = new (std::nothrow) EventListenertouchAllAtOnce(); if (ret && ret->init()) { ret->autorelease(); ret->ontouchesBegan = ontouchesBegan; ret->ontouchesMoved = ontouchesMoved; ret->ontouchesEnded = ontouchesEnded; ret->ontouchesCancelled = ontouchesCancelled; } else { CC_SAFE_DELETE(ret); } return ret;}NS_CC_ENDEventListenertouch是EventListener的子类,具有EventListener的所有属性,加上自身4个属性,共14个属性:
1.ontouchBegan
2.ontouchmove
3.ontouchended
4.ontouchCanceled
5.claimedtouches
6.needSwallow
7.type
8.ListenerID
9.onEvent
10.paused
11.enabled
12.registered
13.node
14.fixedPriority
#ifndef __cocos2d_libs__CCCustomEventListener__#define __cocos2d_libs__CCCustomEventListener__#include "base/CCEventListener.h"NS_CC_BEGINclass EventCustom;/**************************************************************************** 用法: // 1.dispatcher auto dispatcher = Director::getInstance()->getEventdispatcher(); // 2.addListener auto Listener = EventListenerCustom::create("your_event_type",[](EventCustom* event){ do_some_thing(); }); dispatcher->addEventListenerWithSceneGraPHPriority(Listener,one_node); // 3.dispatcherEvent,触发事件。 EventCustom event("your_event_type"); dispatcher->dispatchEvent(&event); ****************************************************************************/// EventCustomclass CC_DLL EventListenerCustom : public EventListener{public: // 当特定的事件被分发,对应callback将会被调用 static EventListenerCustom* create(const std::string& eventname,const std::function<voID(EventCustom*)>& callback); EventListenerCustom(); bool init(const ListenerID& ListenerID,const std::function<voID(EventCustom*)>& callback); /// OverrIDes virtual bool checkAvailable() overrIDe; virtual EventListenerCustom* clone() overrIDe;protected: std::function<voID(EventCustom*)> _onCustomEvent; frIEnd class LuaEventListenerCustom;};NS_CC_END#endif
#include "base/CCEventListenerCustom.h"#include "base/CCEventCustom.h"NS_CC_BEGINEventListenerCustom::EventListenerCustom(): _onCustomEvent(nullptr){}EventListenerCustom* EventListenerCustom::create(const std::string& eventname,const std::function<voID(EventCustom*)>& callback){ EventListenerCustom* ret = new (std::nothrow) EventListenerCustom(); if (ret && ret->init(eventname,callback)) { ret->autorelease(); } else { CC_SAFE_DELETE(ret); } return ret;}bool EventListenerCustom::init(const ListenerID& ListenerID,const std::function<voID(EventCustom*)>& callback){ bool ret = false; // callback ==> Listener. // EventListenerCustom的onCustomEvent 与 EventListener的onEvent相关联。 _onCustomEvent = callback; auto Listener = [this](Event* event){ if (_onCustomEvent != nullptr) { _onCustomEvent(static_cast<EventCustom*>(event)); } }; // event参数的传入 // EventListener::init(Type t,ListenerID ListenerID,std::function<voID(Event*)>& callback) if (EventListener::init(EventListener::Type::CUSTOM,ListenerID,Listener)) { ret = true; } return ret;}EventListenerCustom* EventListenerCustom::clone(){ EventListenerCustom* ret = new (std::nothrow) EventListenerCustom(); if (ret && ret->init(_ListenerID,_onCustomEvent)) { ret->autorelease(); } else { CC_SAFE_DELETE(ret); } return ret;}bool EventListenerCustom::checkAvailable(){ bool ret = false; if (EventListener::checkAvailable() && _onCustomEvent != nullptr) { ret = true; } return ret;}NS_CC_ENDEventListenerCustom是EventListener的子类,共有9个属性:
1.onCustomEvent
2.onEvent
3.type
4.ListenerID
5.registered
6.paused
7.enabled
8.node
9.fixedPriority
总结以上是内存溢出为你收集整理的cocos2d-x 3.7 源码分析 EventDispatcher全部内容,希望文章能够帮你解决cocos2d-x 3.7 源码分析 EventDispatcher所遇到的程序开发问题。
如果觉得内存溢出网站内容还不错,欢迎将内存溢出网站推荐给程序员好友。
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)