auto listener = EventListenerTouchOneByOne::create();
listener->onTouchBegan = [](Touch* touch, Event* event)
{
Point pos1 = touch->getLocation(); //获取单击坐标,基于3D
Point pos2 = touch->getLocationInView(); //获取单击坐标,基于2D
Point pos3 = Director::getInstance()->convertToGL(pos2); //获取单机坐标,基于cocos2d-x
log("HelloWorldScene onTouchBegan! pos1 x=%f,y=%f", pos1.x, pos1.y);
log("HelloWorldScene onTouchBgean! pos2 x=%f,y=%f", pos2.x, pos2.y);
log("HelloWorldScene onTouchBegan! pos3 x=%f,y=%f", pos3.x, pos3.y);
return true;
};
listener->onTouchMoved = [](){
log("HelloWorldScene onTouchMoved!");
};
listener->onTouchEnded = [](){
log("HelloWorldScene onTouchEnded!");
};
_eventDispatcher->addEventListenerWithSceneGraphPriority(listener, this);
常用的触摸事件一般有四个:
1.onTouchBegan:触摸事件的开始,也就是手指按下时;
2.onTouchMoved:触摸移动事件,也就是手指在屏幕滑动时;
3.onTouchEnded:触摸事件结束,也就是手指松开时;
4.onTouchCancelled:打断触摸事件,一般是系统的层级消息,如手机来电话触摸事件就会被中断。
<span style="white-space:pre"> </span>Point pos1 = touch->getLocation(); //获取单击坐标,基于3D
Point pos2 = touch->getLocationInView(); //获取单击坐标,基于2D
Point pos3 = Director::getInstance()->convertToGL(pos2); //获取单机坐标,基于cocos2d-x
第一种方式获取的是三维坐标。
第二种方式获取的是二维坐标,这种方式比较常用,但是,这种方式获取的坐标是左上角为原点的,而cocos2d-x使用的坐标是按照左下角为原点的,也就是笛卡尔坐标系。因此我们要用convertToGL函数将坐标转换成笛卡尔坐标这就是第三中方式。
_eventDispatcher是事件管理器,其实它相当于Director::getInstance()->getEventDispatcher(),是一个单例类。只不过为了方便,在Node类里使用了一个_eventDispatcher变量保存了这个单例类的引用。
消息的截断
Size visibleSize = Director::getInstance()->getVisibleSize();
Sprite* sp1 = Sprite::create("sprite1.png");
sp1->setPosition(Point(visibleSize.width*0.5f, visibleSize.height*0.5f));
this->addChild(sp1);
Sprite* sp2 = Sprite::create("sprite2.png");
sp2->setPosition(Point(visibleSize.width*0.5f, visibleSize.height*0.5f));
this->addChild(sp2);
// 创建两个精灵,相互有重叠的部分
auto listener = EventListenerTouchOneByOne::create();
listener->onTouchBegan = [](Touch* touch, Event* event){
auto target = static_cast<Sprite*>(event->getCurrentTarget());
//注册监听事件时绑定了一个Node对象,在这里就可以取出这个对象
Point pos = Director::getInstance()->convertToGL(touch->getLocationInView());
if (target->getBoundingBox().containsPoint(pos)) //判断单击的坐标是否在精灵的范围内
{
target->setOpacity(100); //设置精灵的透明度为100
return true;
}
return false;
};
listener->onTouchEnded = [](Touch* touch, Event* event)
{
auto target = static_cast<Sprite*>(event->getCurrentTarget());
target->setOpacity(255); //恢复精灵的透明度
};
listener->setSwallowTouches(true); //设置吞没事件
_eventDispatcher->addEventListenerWithSceneGraphPriority(listener, sp1); //注册监听事件,绑定精灵1
_eventDispatcher->addEventListenerWithSceneGraphPriority(listener->clone(), sp2);
第一张图片是截断之前的,第二章是截断之后的。
setSwallowTouches函数用于设置是否吞没事件,也就是说,当某个触摸事件回调时,截断这个事件,让它不能传递给其他人。
注册监听事件就是把listener对象添加到一个列表而已,然后触摸事件发生时,遍历列表,调用这些对应的onTouchBegan等函数。
auto listener = EventListenerTouchOneByOne::create();
我们在注册事件时绑定了一个对象,那么,在触摸事件回调时,可以通过getCurrentTarget函数获取这个绑定的对象。由于获取的对象类型是Node,而我们已经知道这个对象实际上是Sprite,所以需要转换一下。