• cocos2d-x触摸事件优先级的探究与实践


    如何让自定义Layer触发触摸事件?

    bool LayerXXX::init()
    {
      this->setTouchEnabled(true);
    
      CCTouchDispatcher* td = CCDirector::sharedDirector()->getTouchDispatcher();
      td->addTargetedDelegate(this, 0, true); //kCCMenuHandlerPriority - 10
    
      // ...
    }

    CCTouchDispatcher是管理cocos2d-x中所有Touch事件派发的类,

    CCTouchDispatcher中包含了两个CCTouchHandler的列表,
    分别存储StandardTouchHandler和 TargetedTouchHandler。

    属性:
    this->mTouchPriporty

    Layer 优先级越小越高
    越低越先响应事件

    实验一:当两个Layer优先级同等的时候会怎么样呢?

    实验发现,同等优先级下,后添加的Layer先响应事件。

    //-------------------------------
    //Touch1 100
    //Touch2 100
    Touch1Layer* touch1layer = Touch1Layer::create( ccc4f(255,0,0,128), 100, 100 );
    this->addChild( touch1layer );
    touch1layer->setPosition(200, 100);
    
    Touch2Layer* touch2layer = Touch2Layer::create( ccc4f(255,255,0,128), 100, 100 );
    this->addChild( touch2layer );
    touch2layer->setPosition(250, 100);
    
    //结果:
    //Touch2
    //Touch1
    //-------------------------------
    //Touch1 100
    //Touch2 100
    Touch2Layer* touch2layer = Touch2Layer::create( ccc4f(255,255,0,128), 100, 100 );
    this->addChild( touch2layer );
    touch2layer->setPosition(250, 100);
    
    Touch1Layer* touch1layer = Touch1Layer::create( ccc4f(255,0,0,128), 100, 100 );
    this->addChild( touch1layer );
    touch1layer->setPosition(200, 100);
    
    结果:
    Touch1
    Touch2
    -------------------------------
    Touch1 100
    Touch2 99
    Touch2Layer* touch2layer = Touch2Layer::create( ccc4f(255,255,0,128), 100, 100 );
    this->addChild( touch2layer );
    touch2layer->setPosition(250, 100);
    
    Touch1Layer* touch1layer = Touch1Layer::create( ccc4f(255,0,0,128), 100, 100 );
    this->addChild( touch1layer );
    touch1layer->setPosition(200, 100);
    
    //结果:
    //Touch2
    //Touch1
    //说明优先级越小越先触发事件
    //-------------------------------

    如何阻塞事件的向后传递?

    原理:
    mSwallowsTouches = false的时候,该层的touch事件若接受处理后,touch事件穿透,进入下个注册touch事件的layer进行处理

    若mSwallowsTouches = true时,当该层处理touch事件的时候,若bool ccTouchBegan(CCTouch *pTouch, CCEvent *pEvent);
    return true时候,则touch事件被该层接收走,其他优先级较低的,就不会接收到touch事件的处理申请了。

    关于ccTouchBegan的返回值
    true:
    本层的后续Touch事件可以被触发,并阻挡向后层传递
    false:
    本层的后续Touch事件不能被触发,并向后传递

    总结:

    如何阻塞事件的向后传递?

    主要是利用了TargetedTouchDelegate 的一个叫SwallowTouch的参数 ,如果这个开关打开的话,

    比他权限低的handler 是收不到 触摸响应的,这里的权限低的意思是先看priority(priority越低的优先级越高)再看哪个Layer最后addChild进去(越后添加的优先级越高)。

    CCMenu 就是开了Swallow 并且权限为-128(权限是越小越好),所以CCMenu的事件不会出现击穿

    mSwallowsTouches = true 并且 ccTouchBegan 返回 true

    如何让Layer所有触摸同时穿透Begin、Move、End事件?

    mSwallowsTouches = false 并且 ccTouchBegan 返回 true

    ccTouchBegan 返回 true 表示同层处理后续事件(吞噬)
    ccTouchBegan 返回 false 表示同层不处理后续事件(Move End Cancled)  (击穿)

    mSwallowsTouches 设为 true 表示触摸不向下层传递(不一定 如mSwallowsTouches为true began返回false还是会向后传递)
    mSwallowsTouches 设为 false 表示触摸向下层传递(不知有啥用)

    this->mTouchPriporty 越小,越先接收到触摸
    this->mTouchPriporty 同等,越后addChild的越先响应

    如何管理多个对话框的优先级?

    事件的优先级和绘图的优先级的关系和区别?

    VertexZ 又是什么?(VertexZ是openGl的z轴)


    绘图的优先级叫ZOrder

    如何改版绘图的优先级?

    如在容器中通过调用
    this->reorderChild(CCNode* child, int zOrder);

    如何设置触摸事件的优先级?
    CCTouchDispatcher::sharedDispatcher()->setPriority(kCCMenuTouchPriority - 1, layer);

    如何得到触摸事件的优先级?
    this->mTouchPriporty (CCNode类成员 私有变量)

    如何遍历容器获取特定的对象??

    void Touch1Layer::setFocus()
    {
      // 将zorder=1;  priority= kCCMenuTouchPriority - 2;
    
      // 设置zorder
      SceneController::GetInstancePtr()->getCurLayer()->reorderChild(this, 1);
      // 设置优先级
      CCTouchDispatcher::sharedDispatcher()->setPriority(kCCMenuTouchPriority - 2, this);
    }
    
    void Touch1Layer::loseAllFocus()
    {
      // 获取顶层的所有节点
      CCArray* arrChilds = SceneController::GetInstancePtr()->getCurLayer()->getChildren();
    
      for(int i=0; i< arrChilds->count(); i++)
      {
        CCLayerColor* layer = dynamic_cast< CCLayerColor* >( arrChilds->objectAtIndex(i) );
    
        // 跳过自己(不撤销自己的优先级)
        if(layer != NULL && layer != this)
        {
          // 将zorder=0;  priority= kCCMenuTouchPriority - 1;
          SceneController::GetInstancePtr()->getCurLayer()->reorderChild(layer, 0);
          CCTouchDispatcher::sharedDispatcher()->setPriority(kCCMenuTouchPriority - 1, layer);
        }
      }
    }

    如何判断点在矩形内部?

    CCPoint pos = this->getPosition();
    CCSize size = this->getContentSize();
    CCRect rect(pos.x, pos.y, size.width, size.height);
    
    if( CCRect::CCRectContainsPoint(rect, point)  )
    {
    }


    z值大的成员在z值小的成员的上面;

    官方解释:

    Differences between openGL Z vertex and cocos2d Z order:
       - OpenGL Z modifies the Z vertex, and not the Z order in the relation between parent-children
       - OpenGL Z might require to set 2D projection
       - cocos2d Z order works OK if all the nodes uses the same openGL Z vertex. eg: vertexZ = 0

    @warning: Use it at your own risk since it might break the cocos2d parent-children z order

  • 相关阅读:
    根据数组对象中的某个属性值排序
    vue小知识
    vue项目中config文件中的 index.js 配置
    小问题
    原生无缝轮播
    webpack打包提交代码
    echarts
    面试问题
    MySql
    vue-router 跳转原理
  • 原文地址:https://www.cnblogs.com/sevenyuan/p/3154624.html
Copyright © 2020-2023  润新知