cocos2d-x学习笔记(12)屏幕触摸事件
常用的触摸事件一般有4个: onTouchBegan:触摸事件开始,也就是手指按下时; onTouchMoved:触摸移动事件,也就是手指在屏幕滑动的过程; onTouchEnded:触摸事件结束,也就是手指松开时。 onTouchCancelled:打断触摸事件事件,一般是系统层级的消息,如手机来电话,触摸事件就会被中断。 auto listener = EventListenerTouchOneByOne::create(); listener->onTouchBegan = [](Touch* touch,Event* event){ Point pos = touch->getLocation(); 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 onTouchBegan! pos2 x=%f,pos2.x,pos2.y); log("HelloWorldScene onTouchBegan! pos3 x=%f,pos3.x,pos3.y); return true; }; listener->onTouchMoved = [](Touch* touch,Event* event){ log("HelloWorldScene onTouchMoved"); }; listener->onTouchEnded = [=](Touch* touch,Event* event){ log("HelloWorldScene onTouchEnded"); }; _eventDispatcher->addEventListenerWithSceneGraphPriority(listener,this);获取单击屏幕时的坐标: Point pos1 = touch->getLocation(); 获取单击坐标,基于3D Point pos2 = touch->getLocationInView(); 获取单击坐标,基于2D Point pos3 = Director::getInstance()->convertToGL(pos2); 获取单击坐标,基于Cocos2d-x 第一种方式获取的是三维坐标,而Cocos2d-x开发的游戏一般都是二维的,所以这种方式比较少用。 第二种方式获取的是二维坐标,这种方式获取的坐标是以左上角为原点的,而Cocos2d-x使用的坐标是以左下角为原点的,也就是我们数学里常用的笛卡尔坐标系。 所以还要用convertToGL函数将坐标转换为笛卡尔坐标,这就是第三种方式。
触摸事件的函数回调用的也是lambda函数,然后调用addEventListenerWidthSceneGraphPriority函数注册监听事件。 _eventDispatcher是事件管理器,其实它相当于Director::getInstance()->getEventDispatcher(),是一个单例类。只不过为了方便 ,在Node类里使用了一个_eventDispatcher变量保存了这个单例类的引用。 addEventListenerWidthSceneGraphPriority函数的两个参数作用: EventListener* listener:事件监听对象,当触摸事件发生时通过它来回调; Node* node:绑定的对象,当node对象被释放时,监听事件的注册也会被取消,同时,有多个触摸事件发生时(比如几个按钮叠加在一起),会根据node的层次优先回调(越在上面的对象越先回调); addEventListenerWithFixedPriority,它也是用于注册监听事件,但这个函数需要手动指定触摸事件回调的优先级,并且需要手动取消监听事件。
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->setSwallowTouches(true); listener->onTouchBegan = [](Touch* touch,Event* event){ /* 注册监听事件的时候不是绑定了一个Node对象么?在这里就可以取出这个对象 */ auto target = static_cast<Sprite*>(event->getCurrentTarget()); Point pos = Director::getInstance()->convertToGL(touch->getLocationInView()); /* 判断点击的坐标是否在精灵的范围内 */ if (target->getBoundingBox().containsPoint(pos)) { /* 设置精灵的透明度为100 */ target->setOpacity(100); return true; } return false; }; listener->onTouchEnded = [](Touch* touch,Event* event){ /* 恢复精灵的透明度 */ auto target = static_cast<Sprite*>(event->getCurrentTarget()); target->setOpacity(255); }; /* 注册监听事件,绑定精灵1 */ _eventDispatcher->addEventListenerWithSceneGraphPriority(listener,sp1); /* 注册监听事件,绑定精灵2,这里要注意,listener对象拷贝了一个 */ _eventDispatcher->addEventListenerWithSceneGraphPriority(listener->clone(),sp2);1、创建两个精灵,让这两个精灵刚好有部分位置是重叠的; 2、创建EventListenerTouchOneByOne监听事件; 4、在onTouchEnded函数里恢复精灵的透明度为255; 5、调用addEventListenerWidthSceneGraphPriority函数分别添加两个精灵的监听事件。 通常需要得到的效果是,在单击重叠部位的时候,只有上面的按钮能获得响应。 listener->setSwallowTouches(true);setSwallowTouches函数用于设置是否吞没事件,也就是说,当某个触摸事件回调时,截断这个事件,让它不能继续传递给其他人。 (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |