cocos2dx3.0的触摸响应机制有3种,现在我们就来逐一了解这3种http://www.taikr.com/article/801。
第一种是采用函数回调,主要是用于MenuItem
// a selector callback
void menuCloseCallback(Object* pSender);
auto closeItem = MenuItemImage::create(“CloseNormal.png”,“CloseSelected.png”,
CC_CALLBACK_1(HelloWorld::menuCloseCallback, this));
void HelloWorld::menuCloseCallback(Object* pSender)
{
Director::getInstance()->end();
#if (CC_TARGET_PLATFORM == CC_PLATFORM_IOS)
exit(0);
#endif
}
从上面的代码也可以看得到3.0的一些改变
用CC_CALLBACK_x代替了 按钮的 menu_selector(),update的 schedule_selector 回调接口,其中最后一个x代表着回调函数的参数有几个,0表示0个,1表示1个,2表示2个,上面的例子是1个参数,所以用CC_CALLBACK_1
第二种方法我也不是很明白,TouchEvent响应
这是新加入的响应方式。它主要是使用在UIWidget上的。可以将其看做是函数回调的一个扩展,为更多的响应处理提供可能。使用方法大致是:
//声明
void touchButton(Object* object,TouchEventType type);
//挂接到控件上
uiButton->addTouchEventListener(this,toucheventselector(HelloWorld::touchButton));
//实现
void HelloWorld::touchButton(Object* object,TouchEventType type)
{
LabelTTF* label;
switch (type)
{
case TouchEventType::TOUCH_EVENT_BEGAN:
label = static_cast(getChildByTag(11));
label->setString(“按下按钮”);
break;
case TouchEventType::TOUCH_EVENT_MOVED:
label = static_cast(getChildByTag(11));
label->setString(“按下按钮移动”);
break;
case TouchEventType::TOUCH_EVENT_ENDED:
label = static_cast(getChildByTag(11));
label->setString(“放开按钮”);
break;
case TouchEventType::TOUCH_EVENT_CANCELED:
label = static_cast(getChildByTag(11));
label->setString(“取消点击”);
break;
default:
break;
}
}
因为所有的UIWidget都要添加到UILayer上,而UILayer通常都会在最上层,所以可以“基本上”认为这种使用方式会优先于其他方式处理点击消息。因为UILayer也会有层级的改变,比如它和MenuItem之间的关系。所以说“基本上”。
第三种 触摸监听绑定
我觉得这种方法相当方便,不仅可以绑定在精灵上,还可以绑定在层上,触摸函数也可以用lambda来写。下面是方法
auto listener1 = EventListenerTouchOneByOne::create();//创建一个触摸监听
listener1->setSwallowTouches(true);//设置是否想下传递触摸
Rect rect = Rect(qipanPoint.x,qipanPoint.y
,qipanSize.width,qipanSize.height);
//3.0 后可以直接在touchBegan后添加它的实现代码,而不用特意去写一个touchBegan的函数
listener1->onTouchBegan = (Touch* touch, Event* event){ //]中间的是传入的参数
auto target = static_cast(event->getCurrentTarget());//获取的当前触摸的目标
Point locationInNode = target->convertToNodeSpace(touch->getLocation());
Size s = target->getContentSize();
if (rect.containsPoint(locationInNode))//判断触摸点是否在目标的范围内
{“white-space:pre”> //以下是我自定义的一些操作
//创建锁定精灵
auto lockSprite = Sprite::create(“lock.png”);
lockSprite->setPosition(GetQiziPoint(locationInNode,rect));
lockSprite->setTag(99);
this->addChild(lockSprite);
return true;
}else
return false;
};
//拖动精灵移动
listener1->onTouchMoved = (Touch* touch, Event* event){
auto target = static_cast(event->getCurrentTarget());//获取的当前触摸的目标
Point locationInNode = target->convertToNodeSpace(touch->getLocation());
Size s = target->getContentSize();
if (rect.containsPoint(locationInNode))//判断触摸点是否在目标的范围内
{
//锁定精灵移动
Sprite lockSprite = (Sprite)this->getChildByTag(99);
lockSprite->setPosition(GetQiziPoint(locationInNode,rect));
}
};
listener1->onTouchEnded = =](Touch* touch, Event* event){ // =在c++11里面代表这个lambda表达式中能使用外面的变量
this->removeChildByTag(99);//移除锁定精灵
};
//将触摸监听添加到eventDispacher中去
_eventDispatcher->addEventListenerWithSceneGraphPriority(listener1 ,layer);