• Cocos2dx 3.0 提高篇(三) 触摸机制


    转载

     http://blog.csdn.net/start530/article/details/18325493

    Cocos2dx 3.0 提高篇(三) 触摸机制

    分类: cocos2d-x学习笔记 222人阅读 评论(0) 收藏 举报

    本来在中午休息时间打算大展拳脚,好好写一篇新触摸机制相关的博文,结果,等真正下手的时候才发现无从下手,很多地方自己都说不清,赶紧看了下testCpp,才发现原来是这样,还可以这样,哦?这样都行?哎,我还是太年轻了。

    咱也只能挑简单的讲了。

    假设要实现拖动一个精灵移动,那我们的步骤是:

    1、 创建一个精灵sprite

    2、一个触摸事件 listener ,设置listener的onTouchBegan,onTouchMoved,onTouchEnded;

    3、将sprite 和 listener关联起来。

    实现如下:

    1、 创建精灵:

     
    1. Point origin = Director::getInstance()->getVisibleOrigin();  
    2. Size size = Director::getInstance()->getVisibleSize();  
    3.   
    4. auto sprite = Sprite::create("Images/CyanSquare.png");  
    5. sprite->setPosition(origin+Point(size.width/2, size.height/2) + Point(-80, 80));  
    6. addChild(sprite, 1);  

    2、 创建 listener


    1. auto listener1 = EventListenerTouchOneByOne::create();//创建一个触摸监听  
    2. listener1->setSwallowTouches(true);//设置是否想下传递触摸  

    1. //3.0 后可以直接在touchBegan后添加它的实现代码,而不用特意去写一个touchBegan的函数  
    2. listener1->onTouchBegan = [](Touch* touch, Event* event){  
    3. auto target = static_cast<Sprite*>(event->getCurrentTarget());//获取的当前触摸的目标  
    4.       
    5. Point locationInNode = target->convertToNodeSpace(touch->getLocation());  
    6. Size s = target->getContentSize();  
    7. Rect rect = Rect(0, 0, s.width, s.height);  
    8.       
    9. if (rect.containsPoint(locationInNode))//判断触摸点是否在目标的范围内  
    10.       return true;  
    11. else  
    12.       return false;  
    13. };  
    14.   
    15.  //拖动精灵移动  
    16. listener1->onTouchMoved = [](Touch* touch, Event* event){  
    17.     auto target = static_cast<Sprite*>(event->getCurrentTarget());  
    18.     target->setPosition(target->getPosition() + touch->getDelta());  
    19. };  
    20.   
    21. listener1->onTouchEnded = [=](Touch* touch, Event* event){  
    22. };  
    23. //将触摸监听添加到eventDispacher中去  
    24. _eventDispatcher->addEventListenerWithSceneGraphPriority(listener1 ,sprite);  

    1. }  

    以上就是移动一个精灵的实现过程,这里特意交代一些细节:

    1)触摸监听listener的创建方式有两种,一种是:EventListenerTouchOneByOne,另一种是:EventListenerTouchAllAtOnce,顾名思义,EventListenerTouchOneByOne的意思就是一个一个按顺序来的意思,这也是3.0触摸机制不同的地方,只要是放在最上面的那个精灵,那它的触摸优先级就最高。我们用的按钮Menu 就是用这种方式设置触摸优先级的。而EventListenerTouchAllAtOnce,我还没怎么用过,不过看它的意思应该是如果有多个按钮叠加,那你按下去,每个按钮都会响应(纯属个人猜测)。

    2)将listener1添加到事件调度中,这里用的是:


    1. _eventDispatcher->addEventListenerWithSceneGraphPriority(listener1 sprite);  

    我们进入addEventListenerWithSceneGraphPriority的定义中看一下,有下面这一行代码:


    1. listener->setFixedPriority(0);  

    它将精灵的触摸优先级设置成0,从这里我们可以引申出两个问题,一个就是当我们要给精灵设置触摸优先级时,


    1. listener->setFixedPriority(0);  
    ,因为0已经被“官府”征用了,另一个问题就是:如果自己想设置精灵的触摸优先级,那应该怎么做呢?下面是提供的另外一种添加listener的方法:
    1. _eventDispatcher->addEventListenerWithFixedPriority(listener1 ,fixedPriority);  

    在第二个参数里设置触摸优先级,这样就可以了。

    3)如果你有多个精灵sprite,且这些精灵都想实现拖动的功能,那么这些精灵都可以使用listener1这一个触摸监听,例如我们有三个精灵,sprite,sprite2,sprite3,他们调用listener1的方式:


     
    1.  _eventDispatcher->addEventListenerWithSceneGraphPriority(listener1, sprite1);  
    2.  _eventDispatcher->addEventListenerWithSceneGraphPriority(listener1->clone(), sprite2);  
    3. _eventDispatcher->addEventListenerWithSceneGraphPriority(listener1->clone(), sprite3);  

    其中sprite2和sprite3都是克隆了listener1的,进入clone()的定义,我们看到以下代码:


     
    1. EventListenerTouchOneByOne* EventListenerTouchOneByOne::clone()  
    2. {  
    3.     auto ret = new EventListenerTouchOneByOne();  
    4.     if (ret && ret->init())  
    5.     {  
    6.         ret->autorelease();  
    7.           
    8.         ret->onTouchBegan = onTouchBegan;  
    9.         ret->onTouchMoved = onTouchMoved;  
    10.         ret->onTouchEnded = onTouchEnded;  
    11.         ret->onTouchCancelled = onTouchCancelled;  
    12.           
    13.         ret->_claimedTouches = _claimedTouches;  
    14.         ret->_needSwallow = _needSwallow;  
    15.     }  
    16.     else  
    17.     {  
    18.         CC_SAFE_DELETE(ret);  
    19.     }  
    20.     return ret;  
    21. }  

    以上代码主要的目的也就是实现克隆touchbegan,touchmoved,touchended。

    3、删除触摸监听

    如果想移除sprite的触摸移动,可以这么做:

    1. _eventDispatcher->removeEventListeners(EventListener::Type::TOUCH_ONE_BY_ONE);  

    这样就OK了。

    好了,先说到这里吧。今晚公司尾牙请客,喝了蛮多酒的,所以这篇博文写的可能不够周密,望大家见谅。

    3.0新的地方讲的也差不多了,简单的就不多说了,难的我也不懂。所以呢,就这样吧。接下来应该是写一些关于3.0的例子吧。恩。

     

    有人问:3.0bate版本 的 继承layer的LayerColor,想停止LayerColor的触摸调用而使用setTouchEnabled,编译器提示声明被否决,肿么办?有神马替代函数能够停止触摸

     答:将setTouchEnable(),换成setEnable();试试

  • 相关阅读:
    CentOS7源码安装Nginx
    CentOS7 源码安装PHP
    Linux系统终端命令提示符设置
    蓝绿发布方案
    datatable 列名重新排序
    C#后台解析 json 动态解析 通用(Dictionary)
    调用webservice 的时候没法输入参数
    soapui 调用wsdl 步骤以及出现的问题
    多文件压缩
    老毛桃+360急救箱结合(转)
  • 原文地址:https://www.cnblogs.com/AlanShearer/p/3524641.html
Copyright © 2020-2023  润新知