cocos2d-x (四):触摸事件处理机制
来源:互联网 发布:wget和yum 编辑:程序博客网 时间:2024/05/16 14:38
触摸事件可以分为如下四个状态
开始、移动、结束、取消
cocos2d-x使用EventTouch来表示一个触摸事件
触摸点的状态使用 EventCode来表示
class CC_DLL EventTouch : public Event{public: static const int MAX_TOUCHES = 15; enum class EventCode { BEGAN, MOVED, ENDED, CANCELLED }; EventTouch(); inline EventCode getEventCode() const { return _eventCode; }; inline const std::vector<Touch*>& getTouches() const { return _touches; };
}
根据状态不同,同一个触摸点会经历多次事件分发。
首先介绍事件监听器的2种类型
EventListenerTouchOneByOne 监听的是单点触摸
class CC_DLL EventListenerTouchOneByOne : public EventListener{public: static const std::string LISTENER_ID; static EventListenerTouchOneByOne* create(); virtual ~EventListenerTouchOneByOne(); void setSwallowTouches(bool needSwallow); bool isSwallowTouches(); /// Overrides virtual EventListenerTouchOneByOne* clone() override; virtual bool checkAvailable() override; //public: typedef std::function<bool(Touch*, Event*)> ccTouchBeganCallback; typedef std::function<void(Touch*, Event*)> ccTouchCallback; ccTouchBeganCallback onTouchBegan; ccTouchCallback onTouchMoved; ccTouchCallback onTouchEnded; ccTouchCallback onTouchCancelled; CC_CONSTRUCTOR_ACCESS: EventListenerTouchOneByOne(); bool init(); private: std::vector<Touch*> _claimedTouches; bool _needSwallow; friend class EventDispatcher;};
EventListenerTouchAllAtOnce 监听的就是多点触摸
class CC_DLL EventListenerTouchAllAtOnce : public EventListener{public: static const std::string LISTENER_ID; static EventListenerTouchAllAtOnce* create(); 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; CC_CONSTRUCTOR_ACCESS: EventListenerTouchAllAtOnce(); bool init();private: friend class EventDispatcher;};
可以看到这单点触摸和多点触摸成员变量定义的主要区别
EventListenerTouchOneByOne
typedef std::function<bool(Touch*, Event*)> ccTouchBeganCallback;
typedef std::function<void(Touch*, Event*)> ccTouchCallback;
EventListenerTouchAllAtOnce
typedef std::function<void(const std::vector<Touch*>&, Event*)> ccTouchesCallback;
它们都定义了4个回调函数,分别用来处理触摸点的开始、移动、结束及取消4中不同的状态
其中,EventListenerTouchOneByOne里的ccTouchBeganCallback的返回值为bool,因为onTouchBegan是必须实现的,否则将
接收不到任何触摸事件的通知,它的返回值是用来告诉EventDispatcher是否将该触摸点后续的触摸状态传递给订阅者,如果为
fasle,onTouchesMoved、onTouchesEnded、onTouchesCancelled将接收不到任何回调。
setSwallowTouches是用来设置是否阻止一个触摸点向后面的订阅者继续分发的。setSwallowTouches(true)即为阻止,例如通常两个按钮
不能同时处理一个触摸点。
在EventDispaycher内部,每次触摸事件,它首先将每个触摸点单独作用在每个EventListenerTouchOneByOne订阅者上面,然后再将所有触摸点集合作用在每个EventListenerTouchAllAtOnce订阅者上面的
注册订阅者:
可以用如下两种方法来注册一个订阅者
void EventDispatcher::addEventListenerWithSceneGraphPriority(EventListener* listener, Node* node)
void EventDispatcher::addEventListenerWithFixedPriority(EventListener* listener, int fixedPriority)
可以先看下这两种方法的实现方式:
void EventDispatcher::addEventListenerWithSceneGraphPriority(EventListener* listener, Node* node){ CCASSERT(listener && node, "Invalid parameters."); CCASSERT(!listener->isRegistered(), "The listener has been registered."); if (!listener->checkAvailable()) return; listener->setSceneGraphPriority(node); listener->setFixedPriority(0); listener->setRegistered(true); addEventListener(listener);} void EventDispatcher::addEventListenerWithFixedPriority(EventListener* listener, int fixedPriority){ CCASSERT(listener, "Invalid parameters."); CCASSERT(!listener->isRegistered(), "The listener has been registered."); CCASSERT(fixedPriority != 0, "0 priority is forbidden for fixed priority since it's used for scene graph based priority."); if (!listener->checkAvailable()) return; listener->setSceneGraphPriority(nullptr); listener->setFixedPriority(fixedPriority); listener->setRegistered(true); listener->setPaused(false); addEventListener(listener);}
EventDispatcher分发事件的顺序如下:
priority<0,scene graph(priority=0),priority>0
首先分发优先级小于0的订阅者,按优先级从小到大分发,然后分发所有与node元素关联的订阅者,他们按照自身关联的node在ui场景中的层级从前往后分发,最后分发所有有限级大于0的订阅者。也是按照优先级从小到大的顺序分发。
其中的 addEventListenerWithSceneGraphPriority 的事件监听器优先级是 0 ;而且在 addEventListenerWithFixedPriority 中的事件监听器的优先级不可以设置为 0,因为这个是保留给 SceneGraphPriority 使用的
综上所述,我们来看如何实现各种触摸事件
步骤:新建精灵->新建监听器->按需求实现监听器的4个回调函数(onTouchBegan必须实现)->把精灵作为订阅者添加到监听器中
1.单点触摸例子
//新建精灵 auto label = LabelTTF::create("click me ","Courier",30); label->setPosition(size.width/2,size.height/2); addChild(label); //新建监听器 auto listener = EventListenerTouchOneByOne::create(); //按需求实现监听器的4个回调函数(onTouchBegan必须实现) listener->onTouchBegan = [label](Touch * t,Event *e){ if(e->getCurrentTarget()->getBoundingBox().containsPoint(t->getLocation())){ log("onTouchBegan"); } //返回值如果是 false 后面的时间就不会再被触发 返回值是true TouchMoved End会被触发 return false; }; listener->onTouchMoved = [](Touch *t ,Event *e){ log("onTouchMoved"); }; listener->onTouchEnded = [](Touch *t,Event *e){ log("onTouchEnded"); }; //把精灵作为订阅者添加到监听器中 Director::getInstance()->getEventDispatcher()->addEventListenerWithSceneGraphPriority(listener,label);
2.多点触摸
多点触摸实现过程与单点触摸类似
auto listener = EventListenerTouchAllAtOnce::create(); listener->onTouchesBegan=[](std::vector<Touch*> s,Event *e){ log("onTouchesBegan"); return true; }; listener->onTouchesMoved=[](std::vector<Touch*> s,Event *e) { }; Director::getInstance()->getEventDispatcher()->addEventListenerWithSceneGraphPriority(listener,this);
3.加速度传感器
//加速度传感器默认是关闭的 Device::setAccelerometerEnabled(true); //加速度传感器 Director::getInstance()->getEventDispatcher()-> addEventListenerWithSceneGraphPriority( EventListenerAcceleration::create([](Acceleration *a,Event *e){ log("x:%g,y:%g,z:%g",a->x,a->y,a->z); }),this);
4.物理按键
物理按键对手机来说通常就是指返回键,如下便是当手机按下返回键的时候进行的处理
auto listener = EventListenerKeyboard::create();listener->onKeyReleased=[](EventKeyboard::KeyCode code,Event *e){ log("key code: %d",code); switch (code) { case EventKeyboard::KeyCode::KEY_BACKSPACE: Director::getInstance()->end(); break; default: break; }};Director::getInstance()->getEventDispatcher()->addEventListenerWithSceneGraphPriority(listener,this);
0 0
- cocos2d-x (四):触摸事件处理机制
- cocos2d-x 触摸事件处理机制
- Cocos2d-x 3.0 触摸事件处理机制
- Cocos2d-x 3.0 触摸事件处理机制
- Cocos2d-x 3.0 新特性体验-触摸事件处理机制
- Cocos2d-x事件交互处理(触摸处理)
- cocos2d-x触摸机制--用户交互事件
- Cocos2d-x之Touch事件处理机制 提供两种触摸事件处理机制:CCStandardTouchDelegate和CCTargetedTouchDelegate。
- Cocos2d-x 3.0 新特性体验(3)触摸事件处理机制
- Cocos2d-x 3.0 新特性体验(3)触摸事件处理机制
- Cocos2d-x 3.0 新特性体验(3)触摸事件处理机制
- cocos2d-x 事件分发机制 ——触摸事件监听
- cocos2d-x 事件分发机制 ——触摸事件监听
- cocos2d-x 事件分发机制 ——触摸事件监听
- cocos2d-x 3.0 事件分发机制 —触摸事件监听
- cocos2d-x v3.2 触摸事件派发机制
- cocos2d-x 3.0 全新触摸检测与事件分发机制
- Cocos2d-x游戏开发之处理单点触摸事件
- 第六届蓝桥杯JavaA组 第八题 移动距离
- PostgreSQL 常用数据类型
- 【机器学习】(4):监督式学习
- 指令集简介
- 海量数据处理算法—Bloom Filter
- cocos2d-x (四):触摸事件处理机制
- CSS3的[att*=val]选择器
- 【概念对比】编程语言之强类型与弱类型
- 最长回文子串
- 一个java的TCP通信例子
- 2015年第六届蓝桥杯省赛(C/C++ B组)解题报告
- apache2支持php的多种方法
- POJ 3664----Election Time
- js:window.onload的使用