cocos2dx3.0的触摸响应机制有3种,现在我们就来逐一了解这3种触摸响应机制。

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

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

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

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

这是新加入的响应方式。它主要是使用在UIWidget上的。可以将其看做是函数回调的一个扩展,为更多的响应处理提供可能。使用方法大致是:
  1. [cpp] 
  2. //声明
  3. void touchButton(Object* object,TouchEventType type);
  4. //挂接到控件上
  5. uiButton->addTouchEventListener(this,toucheventselector(HelloWorld::touchButton));
  6. //实现
  7. void HelloWorld::touchButton(Object* object,TouchEventType type)
  8. {
  9. LabelTTF* label;
  10. switch (type)
  11. {
  12. case TouchEventType::TOUCH_EVENT_BEGAN:
  13. label = static_cast(getChildByTag(11));
  14. label->setString("按下按钮");
  15. break;
  16. case TouchEventType::TOUCH_EVENT_MOVED:
  17. label = static_cast(getChildByTag(11));
  18. label->setString("按下按钮移动");
  19. break;
  20. case TouchEventType::TOUCH_EVENT_ENDED:
  21. label = static_cast(getChildByTag(11));
  22. label->setString("放开按钮");
  23. break;
  24. case TouchEventType::TOUCH_EVENT_CANCELED:
  25. label = static_cast(getChildByTag(11));
  26. label->setString("取消点击");
  27. break;
  28. default:
  29. break;
  30. }
  31. }
因为所有的UIWidget都要添加到UILayer上,而UILayer通常都会在最上层,所以可以“基本上”认为这种使用方式会优先于其他方式处理点击消息。因为UILayer也会有层级的改变,比如它和MenuItem之间的关系。所以说“基本上”。

第三种 触摸监听绑定

我觉得这种方法相当方便,不仅可以绑定在精灵上,还可以绑定在层上,触摸函数也可以用lambda来写。下面是方法
  1. [cpp]
  2. auto listener1 = EventListenerTouchOneByOne::create();//创建一个触摸监听
  3. listener1->setSwallowTouches(true);//设置是否想下传递触摸
  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. Point locationInNode = target->convertToNodeSpace(touch->getLocation());
  10. Size s = target->getContentSize();
  11. if (rect.containsPoint(locationInNode))//判断触摸点是否在目标的范围内
  12. {"white-space:pre"> //以下是我自定义的一些操作
  13. //创建锁定精灵
  14. auto lockSprite = Sprite::create("lock.png");
  15. lockSprite->setPosition(GetQiziPoint(locationInNode,rect));
  16. lockSprite->setTag(99);
  17. this->addChild(lockSprite);
  18. return true;
  19. }else
  20. return false;
  21. };
  22. //拖动精灵移动
  23. listener1->onTouchMoved = [rect,this](Touch* touch, Event* event){
  24. auto target = static_cast(event->getCurrentTarget());//获取的当前触摸的目标
  25. Point locationInNode = target->convertToNodeSpace(touch->getLocation());
  26. Size s = target->getContentSize();
  27. if (rect.containsPoint(locationInNode))//判断触摸点是否在目标的范围内
  28. {
  29. //锁定精灵移动
  30. Sprite *lockSprite = (Sprite*)this->getChildByTag(99);
  31. lockSprite->setPosition(GetQiziPoint(locationInNode,rect));
  32. }
  33. };
  34. listener1->onTouchEnded = [=](Touch* touch, Event* event){ // =在c++11里面代表这个lambda表达式中能使用外面的变量
  35. this->removeChildByTag(99);//移除锁定精灵
  36. };
  37. //将触摸监听添加到eventDispacher中去
  38. _eventDispatcher->addEventListenerWithSceneGraphPriority(listener1 ,layer);