最新稳定版本的3.0版本对原先的一些方法都做了修改,其中就包括了关于触摸机制这方面:
在.h中声明还是和之前一样
首先加入命名空间USING_NS_CC;
bool onTouchBegan(Touch* touch, Event* event);
void onTouchMoved(Touch* touch, Event* event);
void onTouchEnded(Touch* touch, Event* event);
auto touchListener = EventListenerTouchOneByOne::create();
touchListener->onTouchBegan = CC_CALLBACK_2(HelloWorld::onTouchBegan, this);
touchListener->onTouchMoved = CC_CALLBACK_2(HelloWorld::onTouchMoved, this);
touchListener->onTouchEnded = CC_CALLBACK_2(HelloWorld::onTouchEnded, this);
_eventDispatcher->addEventListenerWithSceneGraphPriority(touchListener, this);
EventListenerTouchOneByOne 表示的是单点触摸;
而EventListenerTouchAllAtOnce 表示的就是多点触摸
_eventDispatcher
事件监听器包含以下几种:
- 触摸事件 (EventListenerTouch)
- 键盘响应事件 (EventListenerKeyboard)
- 加速记录事件 (EventListenerAcceleration)
- 鼠标响应事件 (EventListenerMouse)
- 自定义事件 (EventListenerCustom)
以上事件监听器统一由_eventDispatcher来进行管理。
_eventDispatcher 是 Node 的属性,通过它管理当前节点(如 场景 、层、精灵等 )的所有事件分发情况。但是它本身是一个单例模式值的引用,在 Node 构造函数中,通过 "Director::getInstance()->getEventDispatcher();" 获取,有了这个属性,我们能更为方便的调用。
关于触摸事件3.0有2种写法:
第一种跟之前的版本一样:
bool demo1::onTouchBegan(Touch* touch, Event* event){
auto target = static_cast<Sprite*>(event->getCurrentTarget());//获取到设置触摸事件的精灵
Point locationInNode = target->convertToNodeSpace(touch->getLocation());//获取到点击的坐标,转换为一个节点
Size s = target->getContentSize();
Rect rect = Rect(0, 0, s.width, s.height);
if (rect.containsPoint(locationInNode))//判断点击的点,是否在矩形中
{
log("sprite began... x = %f, y = %f", locationInNode.x, locationInNode.y);
target->setOpacity(180);//设置透明度
return true;
}
return false;
}
void demo1::onTouchMoved(Touch* touch, Event* event){
}
void demo1::onTouchEnded(Touch* touch, Event* event){
auto target = static_cast<Sprite*>(event->getCurrentTarget());
log("sprite onTouchesEnded.. ");
target->setOpacity(255);
}
第二种方式为:
采用这个方法,就无需在头文件定义触摸事件了。
listener1->onTouchBegan = [](Touch* touch, Event* event){
auto target = static_cast<Sprite*>(event->getCurrentTarget());
Point locationInNode = target->convertToNodeSpace(touch->getLocation());
Size s = target->getContentSize();
Rect rect = Rect(0, 0, s.width, s.height);
if (rect.containsPoint(locationInNode))
{
log("sprite began... x = %f, y = %f", locationInNode.x, locationInNode.y);
target->setOpacity(180);
return true;
}
return false;
};
listener1->onTouchMoved = [](Touch* touch, Event* event){
auto target = static_cast<Sprite*>(event->getCurrentTarget());
target->setPosition(target->getPosition() + touch->getDelta());
};
listener1->onTouchEnded = [=](Touch* touch, Event* event){
auto target = static_cast<Sprite*>(event->getCurrentTarget());
log("sprite onTouchesEnded.. ");
target->setOpacity(255);
if (target == sprite2)
{
containerForSprite1->setLocalZOrder(100);
}
else if(target == sprite1)
{
containerForSprite1->setLocalZOrder(0);
}
};
2段代码实现的功能是一样的。 注意点:
注意:(1) 这里当我们再次使用 listener1 的时候,需要使用 clone()
方法创建一个新的克隆,因为在使用 addEventListenerWithSceneGraphPriority
或者 addEventListenerWithFixedPriority
方法时,会对当前使用的事件监听器添加一个已注册的标记,这使得它不能够被添加多次。
_eventDispatcher->addEventListenerWithSceneGraphPriority(listener1->clone(), sprite2);
_eventDispatcher->addEventListenerWithSceneGraphPriority(listener1->clone(), sprite3);
(2)清除事件监听的方法:
四种常用的方法,根据不用需要使用
//_eventDispatcher->removeEventListenersForType(EventListener::Type::TOUCH_ONE_BY_ONE);//删除指定类型的监听事件
_eventDispatcher->removeEventListenersForTarget(sp2);//删除指定精灵的监听事件
_eventDispatcher->removeEventListener(touchListener);//删除指定的触摸事件
_eventDispatcher->removeAllEventListeners();//删除所有