cocos2d-x 3.0 触摸机制的使用

前端之家收集整理的这篇文章主要介绍了cocos2d-x 3.0 触摸机制的使用前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。

http://blog.csdn.net/decajes/article/details/38233645


cocos2d-x 3.0版本的事件分发的机制较之之前的版本进行了修改,把事件处理的逻辑分离出来,并通过不同的事件监听器来监听不同的事件。当一个节点收到了事件,就会指派一个事件分发器_eventDispatcher专门来分发这些事件。对于触摸来说,大概的过程就是我们先创建一个对应触摸事件的监听器,然后覆盖触摸事件的函数,并把它们绑定到监听器,然后可以设置一下这个监听器的属性,最后把监听器添加到分发器之中,系统就会自动进行触摸事件的处理。

我们先看看单点触摸的使用,下面是源代码中关于单点触摸监听器的类,可以看到

  1. classEventListenerTouchOneByOne:publicEventListener
  2. {
  3. public:
  4. staticconststd::stringLISTENER_ID;
  5. staticEventListenerTouchOneByOne*create();
  6. virtual~EventListenerTouchOneByOne();
  7. voidsetSwallowTouches(boolneedSwallow);
  8. boolisSwallowTouches();
  9. ///Overrides
  10. virtualEventListenerTouchOneByOne*clone()override;
  11. virtualboolcheckAvailable()override;
  12. //
  13. std::function<bool(Touch*,Event*)>onTouchBegan;
  14. std::function<void(Touch*,Event*)>onTouchMoved;
  15. std::function<private:
  16. EventListenerTouchOneByOne();
  17. boolinit();
  18. std::vector<Touch*>_claimedTouches;
  19. bool_needSwallow;
  20. friendclassEventDispatcher;
  21. };</span>

这个类看上去比较容易理解,下面我们用代码来演示一下怎么使用。在HelloWorld的init函数注册监听器并添加到事件分发器中去。

copy

    //添加一个测试的精灵
  1. autoonion=Sprite::create("onion.png");
  2. onion->setPosition(Point(visibleSize.width/2,visibleSize.height/2));
  3. onion->setScale(0.2);
  4. this->addChild(onion);
  5. //创建一个触摸监听器,这里使用单点触摸事件
  6. autoTouchListenr=EventListenerTouchOneByOne::create();
  7. //设置吞噬为true,不让触摸往下传递
  8. TouchListenr->setSwallowTouches(true);
  9. //和回调函数绑定
  10. TouchListenr->onTouchBegan=CC_CALLBACK_2(HelloWorld::onTouchBegan,this);
  11. TouchListenr->onTouchMoved=CC_CALLBACK_2(HelloWorld::onTouchMoved,153); background-color:inherit; font-weight:bold">this);
  12. TouchListenr->onTouchEnded=CC_CALLBACK_2(HelloWorld::onTouchEnded,0); background-color:inherit">//添加监听器到事件分发器中
  13. _eventDispatcher->addEventListenerWithSceneGraPHPriority(TouchListenr,onion);

下面我们覆盖单点触摸中提供的触摸函数

copy

    boolHelloWorld::onTouchBegan(Touch*touch,Event*event)
  1. //获取精灵对象并取得精灵的矩阵
  2. autosprite=static_cast<Sprite*>(event->getCurrentTarget());
  3. Rectrect=sprite->getBoundingBox();
  4. //获取触摸点的坐标
  5. Pointpoint=touch->getLocation();
  6. //判断触摸点是否在精灵的矩阵范围内
  7. if(rect.containsPoint(point))
  8. returntrue;
  9. }
  10. false;
  11. voidHelloWorld::onTouchMoved(Touch*touch,0); background-color:inherit">//获取精灵对象
  12. //改变精灵的位置
  13. sprite->setPosition(sprite->getPosition()+touch->getDelta());
  14. }
  15. voidHelloWorld::onTouchEnded(Touch*touch,Event*event)
  16. {
  17. CCLog("touchend!");
  18. }

点击调试运行,可以在屏幕中拉动所测试的精灵,如下图:


在上面的例子中我们看到了,传递过来的参数主要有Touch* touch和Event* event,我们可以进入源代码中查看他们的作用。Touch类是继承了REF,查看源代码中的主要成员如下:

copy

    /**returnsthecurrenttouchlocationinOpenGLcoordinates*/
  1. PointgetLocation()const;
  2. /**returnstheprevIoUstouchlocationinOpenGLcoordinates*/
  3. PointgetPrevIoUsLocation()/**returnsthestarttouchlocationinOpenGLcoordinates*/
  4. PointgetStartLocation()/**returnsthedeltaof2currenttoucheslocationsinscreencoordinates*/
  5. PointgetDelta()/**returnsthecurrenttouchlocationinscreencoordinates*/
  6. PointgetLocationInView()/**returnstheprevIoUstouchlocationinscreencoordinates*/
  7. PointgetPrevIoUsLocationInView()/**returnsthestarttouchlocationinscreencoordinates*/
  8. PointgetStartLocationInView()const;

也就是Touch传入的是触摸点的坐标位置,并且Touch类为我们提供一些坐标的写法,那么我们就方便很多了。譬如上面例子中的触摸移动时,Touch就为我提供一个getDelta()来计算点的位移。

而对于Event类,主要是传入处理的对象,看源代码有以下主要成员:

copy

    /**Getstheeventtype*/
  1. inlineTypegetType()const{return_type;};
  2. /**Stopspropagationforcurrentevent*/
  3. inlinevoidstopPropagation(){_isStopped=true;};
  4. /**Checkswhethertheeventhasbeenstopped*/
  5. inlineboolisStopped()const{return_isStopped;};
  6. /**@briefGetscurrenttargetoftheevent
  7. *@returnThetargetwithwhichtheeventassociates.
  8. *@noteItonlysbeavailablewhentheeventlistenerisassociatedwithnode.
  9. *Itreturns0whenthelistenerisassociatedwithfixedpriority.
  10. */
  11. inlineNode*getCurrentTarget(){return_currentTarget;};

那么我们在处理触摸对象的时候和例子那样通过getCurrentTarget()来获取对象并处理即可。

另一方面,我们在把监听器添加到事件分发器的时候,会看到代码提示两种方法,一个为:addEventListenerWithSceneGraPHPriority,另一个为addEventListenerWithFixedPriority。同样可以查看源代码如下:

copy

    /**AddSAEventlistenerforaspecifiedeventwiththepriorityofscenegraph.
  1. *@paramlistenerThelistenerofaspecifiedevent.
  2. *@paramnodeThepriorityofthelistenerisbasedonthedraworderofthisnode.
  3. *@noteThepriorityofscenegraphwillbefixedvalue0.Sotheorderoflisteneritem
  4. *inthevectorwillbe'<0,scenegraph(0priority),>0'.
  5. */
  6. voidaddEventListenerWithSceneGraPHPriority(EventListener*listener,Node*node);
  7. /**AddSAEventlistenerforaspecifiedeventwiththefixedpriority.
  8. *@paramfixedPriorityThefixedpriorityofthelistener.
  9. *@noteAlowerprioritywillbecalledbeforetheonesthathaveahighervalue.
  10. *0priorityisforbiddenforfixedprioritysinceit'susedforscenegraphbasedpriority.
  11. voidaddEventListenerWithFixedPriority(EventListener*listener,intfixedPriority);

根据注释可以知道,前者的触发优先级是按照第二个参数中的node的显示顺序来确定的,而且默认的fixedPriority为0,也就是如果精灵位置靠前,则会优先响应触摸。而后者按照第二个参数的整形变量值的大小来确定的,而且不能为0,值越小那么优先响应触摸。两者除了优先级不一样,移除的过程也有差异。前者会在触摸对象对应的node析构之后系统会帮我们调用移除触摸,但是后者就需要我们手动移除,这一点要注意。

下面我们可以修改上述例子的代码添加多两个精灵,然后在分发事件代码添加

copy

    _eventDispatcher->addEventListenerWithSceneGraPHPriority(TouchListenr->clone(),onion2);
  1. _eventDispatcher->addEventListenerWithSceneGraPHPriority(TouchListenr->clone(),onion3);

点击运行可以测试一下,没有问题。要是想使用addEventListenerWithFixedPriority的方式的话,虽然可以自定义优先级,但是由于没有绑定node对象,所以还需要在触摸函数中引入需要控制的对象才行。但是最后别忘了使用_eventDispatcher->removeEventListener(listerName);来实现监听器的移除。

多点触摸和单点触摸类似,看下面多点触摸监听器的源码。

copy

    classEventListenerTouchAllAtOnce:staticEventListenerTouchAllAtOnce*create();
  1. virtual~EventListenerTouchAllAtOnce();
  2. virtualEventListenerTouchAllAtOnce*clone()override;
  3. void(conststd::vector<Touch*>&,Event*)>onTouchesBegan;
  4. private:
  5. EventListenerTouchAllAtOnce();
  6. boolinit();
  7. classEventDispatcher;
  8. };

可以发现多点触摸就是传入多个Touch对象而已,然后处理的时候可以遍历vector<Touch*>来逐个处理每一个点,例子可以参考源码自带的例子MutiTouchTest。


文章写到这里为止,如有理解不当,请不吝赐教,谢谢。

原文链接:https://www.f2er.com/cocos2dx/342808.html

猜你在找的Cocos2d-x相关文章