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,pos2.x,pos2.y); log("HelloWorldScene onTouchBegan! pos3 x=%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,所以需要转换一下。