3.x的触摸响应机制

Posted feizuzu

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了3.x的触摸响应机制相关的知识,希望对你有一定的参考价值。

第一种是采用函数回调,主要是用于MenuItem

  1. // selector callback  
  2. void menuCloseCallback(Object* pSender);  
  3.   
  4. auto closeItem MenuItemImage::create("CloseNormal.png","CloseSelected.png",  
  5.                         CC_CALLBACK_1(HelloWorld::menuCloseCallback, this));  
  6.   
  7. void HelloWorld::menuCloseCallback(Object* pSender)  
  8.  
  9.     Director::getInstance()->end();  
  10.   
  11. #if (CC_TARGET_PLATFORM == CC_PLATFORM_ios 
  12.     exit(0);  
  13. #endif  
  14.  
从上面的代码也可以看得到3.0的一些改变

用CC_CALLBACK_x代替了 按钮的 menu_selector(),update的 schedule_selector 回调接口,其中最后一个x代表着回调函数的参数有几个,0表示0个,1表示1个,2表示2个,上面的例子是1个参数,所以用CC_CALLBACK_1

第二种方法我也不是很明白,TouchEvent响应

      这是新加入的响应方式。它主要是使用在UIWidget上的。可以将其看做是函数回调的一个扩展,为更多的响应处理提供可能。使用方法大致是:

  1. //声明  
  2. void touchButton(Object* object,TouchEventType type);  
  3.   
  4. //挂接到控件上  
  5. uiButton->addTouchEventListener(this,toucheventselector(HelloWorld::touchButton));  
  6.   
  7. //实现  
  8. void HelloWorld::touchButton(Object* object,TouchEventType type)  
  9.  
  10.     LabelTTF* label;  
  11.     switch (type)  
  12.      
  13.     case TouchEventType::TOUCH_EVENT_BEGAN:  
  14.         label static_cast(getChildByTag(11));  
  15.         label->setString("按下按钮");  
  16.         break;  
  17.     case TouchEventType::TOUCH_EVENT_MOVED:  
  18.         label static_cast(getChildByTag(11));  
  19.         label->setString("按下按钮移动");  
  20.         break;  
  21.     case TouchEventType::TOUCH_EVENT_ENDED:  
  22.         label static_cast(getChildByTag(11));  
  23.         label->setString("放开按钮");  
  24.         break;  
  25.     case TouchEventType::TOUCH_EVENT_CANCELED:  
  26.         label static_cast(getChildByTag(11));  
  27.         label->setString("取消点击");  
  28.         break;  
  29.     default:  
  30.         break;  
  31.      
  32.  

因为所有的UIWidget都要添加到UILayer上,而UILayer通常都会在最上层,所以可以“基本上”认为这种使用方式会优先于其他方式处理点击消息。因为UILayer也会有层级的改变,比如它和MenuItem之间的关系。所以说“基本上”。


第三种 触摸监听绑定

我觉得这种方法相当方便,不仅可以绑定在精灵上,还可以绑定在层上,触摸函数也可以用lambda来写。下面是方法

  1. auto listener1 EventListenerTouchOneByOne::create();//创建一个触摸监听    
  2. listener1->setSwallowTouches(true);//设置是否想下传递触摸    
  3.   
  4. Rect rect Rect(qipanPoint.x,qipanPoint.y  
  5.     ,qipanSize.width,qipanSize.height);  
  6. //3.0 后可以直接在touchBegan后添加它的实现代码,而不用特意去写一个touchBegan的函数  
  7. listener1->onTouchBegan [rect,this](Touch* touch, Event* event){ //[]中间的是传入的参数  
  8.     auto target static_cast(event->getCurrentTarget());//获取的当前触摸的目标  
  9.   
  10.     Point locationInNode target->convertToNodeSpace(touch->getLocation());  
  11.     Size target->getContentSize();  
  12.   
  13.     if (rect.containsPoint(locationInNode))//判断触摸点是否在目标的范围内  
  14.     {"white-space:pre"> //以下是我自定义的一些操作  
  15.         //创建锁定精灵  
  16.         auto lockSprite Sprite::create("lock.png");  
  17.         lockSprite->setPosition(GetQiziPoint(locationInNode,rect));  
  18.         lockSprite->setTag(99);  
  19.         this->addChild(lockSprite);  
  20.         return true;  
  21.     }else  
  22.         return false;  
  23. };  
  24.   
  25. //拖动精灵移动  
  26. listener1->onTouchMoved [rect,this](Touch* touch, Event* event){  
  27.     auto target static_cast(event->getCurrentTarget());//获取的当前触摸的目标  
  28.   
  29.     Point locationInNode target->convertToNodeSpace(touch->getLocation());  
  30.     Size target->getContentSize();  
  31.   
  32.     if (rect.containsPoint(locationInNode))//判断触摸点是否在目标的范围内  
  33.      
  34.         //锁定精灵移动  
  35.         Sprite *lockSprite (Sprite*)this->getChildByTag(99);  
  36.         lockSprite->setPosition(GetQiziPoint(locationInNode,rect));  
  37.      
  38. };  
  39.   
  40. listener1->onTouchEnded [=](Touch* touch, Event* event){ // =在c++11里面代表这个lambda表达式中能使用外面的变量  
  41.     this->removeChildByTag(99);//移除锁定精灵  
  42. };  
  43. //将触摸监听添加到eventDispacher中去  
  44. _eventDispatcher->addEventListenerWithSceneGraphpriority(listener1 ,layer); 

第四种

  1. auto listener = EventListenerTouchOneByOne::create();//创建一个触摸监听(单点触摸)  
  2. listener->onTouchBegan = CC_CALLBACK_2(HelloWorld::onTouchBegan, this);//指定触摸的回调函数  
  3. _eventDispatcher->addEventListenerWithSceneGraphPriority(listener,listen_layer);//将listener和layer绑定,放入事件委托中  
  4.   
  5. bool HelloWorld::onTouchBegan(Touch* touch, Event  *event)  
  6. {  
  7.     auto point = Director::getInstance()->convertToGL(touch->getLocationInView());//获得当前触摸的坐标  
  8.     auto rect = Rect(160-30,400-30,60,60);//设置框坐标和大小处于close 按钮的位置上  
  9.   
  10.     if(rect.containsPoint(point))//如果触点处于rect中  
  11.     {  
  12.         auto menu = (Menu*)this->getChildByTag(99);//通过tag获取到menu  
  13.         auto item = (MenuItem*)menu->getChildByTag(99);//通过tag从menu中获取item  
  14.         item->activate();//让item响应  
  15.     }  
  16.   
  17.     return true;//返回true表示接收触摸事件  
  18. }  





以上是关于3.x的触摸响应机制的主要内容,如果未能解决你的问题,请参考以下文章

iOS之事件的传递和响应机制-原理篇

IOS 触摸事件分发机制详解

响应者链和Hit-Test 机制

iOS触摸事件深度解析-备用

AndroidUI进阶--触摸反馈和事件分发源码解析

quick-cocos2d-x游戏开发——单点触摸