• 关于Cocos2d-x事件处理机制


    事件处理步骤:

    1.创建一个触摸事件监听器(单点触摸或多点触摸)

    2.实现触摸事件的响应方法

    3.添加事件监听器(场景优先或固定值优先)

    4.当用户触摸时,事件分发器就会将事件分发给监听器进行响应

      首先,用户点击屏幕,这时候cocos会把用户点击的信息,包括点击的坐标,优先顺序的值...等等,包含在一个Touch类型的变量中,可以是t。然后把这个信息传递给事件分发器,再由事件分发器分发给相应的事件监听器。事件监听器根据事件的类型,就是一个Event类型的变量,可以是e。决定要响应什么样的动作,这个响应的动作可以用Lambda表达式为架构,里面放上一个回调函数。

      一个事件监听器可以有多个事件处理响应的Lambda表达式,但是只能响应一个实例对象,这个实例对象可以是this(其实是指layer),或者sprite,或者其他的Node类的子类。而且事件分发器只允许注册一次监听器,也就是在事件分发器里面不能有重名的监听器。所以,如果要让多个对象都可以被监听到相同的监听器,可以在注册监听器的时候用listener1->clone(),sprite2。

      listener1->setSwallowTouches(true)是设置是否吞并事件,我们平时点击或者触摸的时候,如果有多个对象重叠的时候,而且每个重叠的对象都有自己的监听器和响应的Lambda。如果我们把它设置为true,吞并触摸,那么事件响应的时候只响应最上层的那个对象,就是只处理最上层对象的事件传递和响应。而如果我们把它设置成false,那么事件响应的时候会按照对象zOrder的大小来依次处理各个对象的事件传递和响应。也就是不吞并触摸,让所有在这一点下的对象都被触摸到,而不是被最上层的对象吞掉。

    实例代码:

    bool HelloWorld::init()
    {
    if (!Layer::init())
    {
    return false;
    }
    auto visibleSize = Director::getInstance()->getVisibleSize();
    Vec2 origin = Director::getInstance()->getVisibleOrigin();

    //删除触摸监听器
    auto removeAllTouchItem = MenuItemFont::create("shanchu suoyou de chumo jiantingqi", [this](Ref * sender){
      auto senderItem = static_cast<MenuItemFont*>(sender);
      senderItem->setString("chumo jiantingqi shanchu chenggong");
      _eventDispatcher->removeEventListenersForType(EventListener::Type::TOUCH_ONE_BY_ONE);
    });
    removeAllTouchItem->setPosition(visibleSize.width / 2, visibleSize.height*0.2);

    //标题标签
    auto title = Label::createWithSystemFont("dan dian chumo ceshi", "", 64);
    title->setPosition(visibleSize.width / 2, visibleSize.height*0.9);
    this->addChild(title);

    //提示标签
    auto subtitle = Label::createWithSystemFont("qing dan ji huozhe tuo dong huakuai", "", 32);
    subtitle->setPosition(visibleSize.width / 2, visibleSize.height*0.8);
    this->addChild(subtitle);

    //创建三个精灵对象
    auto sprite1 = Sprite::create("CyanSquare.png");
    sprite1->setPosition(Vec2(visibleSize.width / 2, visibleSize.height / 2) + Vec2(-80, 80));
    addChild(sprite1, 10);

    auto sprite2 = Sprite::create("MagentaSquare.png");
    sprite2->setPosition(Vec2(visibleSize.width / 2, visibleSize.height / 2));
    addChild(sprite2, 20);

    auto sprite3 = Sprite::create("YellowSquare.png");
    sprite3->setPosition(Vec2(0, 0));
    sprite2->addChild(sprite3, 1);

    //创建一个单点触摸事件监听器,处理触摸事件逻辑
    auto listener1 = EventListenerTouchOneByOne::create();
    //设置是否向下传递触摸
    listener1->setSwallowTouches(true);
    //通过Lambda表达式直接实现触摸事件的响应方法
    listener1->onTouchBegan = [](Touch * touch, Event * event){
    auto target = static_cast<Sprite*>(event->getCurrentTarget());
    Point locationInNode = target->convertToNodeSpace(touch->getLocation());

    Size s = target->getContentSize();
    Rect rect = Rect(0, 0, s.width, s.height);
    if (rect.containsPoint(locationInNode))
    {
      log("OnTouchBegan...x=%f,y=%f", locationInNode.x, locationInNode.y);
      target->setOpacity(180);
      return true;
    }
    return false;
    };

    listener1->onTouchMoved = [](Touch * touch, Event * event){
      log("OnTouchMoved...");
      auto target = static_cast<Sprite*>(event->getCurrentTarget());
      target->setPosition(target->getPosition() + touch->getDelta());
    };

    listener1->onTouchEnded = [=](Touch * touch, Event * event){
      auto target = static_cast<Sprite*>(event->getCurrentTarget());
      target->setOpacity(255);
      std::string name;
      if (target == sprite2)
      {
        name = "MagentaSquare.png";
        sprite1->setZOrder(100);
        subtitle->setString("xiang ying shijian de shi jiuhongse,qingse de Zorder zhi bei xiu gai wei100");

      }
      else if (target == sprite1)
      {
        name = "CyanSquare.png";
        sprite1->setZOrder(0);
        subtitle->setString("xiang ying shijian de shi qingse ,qingse de Zorder zhi bei xiu gai wei 0");
      }
      else
      {
        name = "YellowSquare.png";
      }
      log("OnTocuhEnded...your touch is%s", name.c_str());
    };

    //添加场景优先事件监听器
    _eventDispatcher->addEventListenerWithSceneGraphPriority(listener1, sprite1);
    _eventDispatcher->addEventListenerWithSceneGraphPriority(listener1->clone(), sprite2);
    _eventDispatcher->addEventListenerWithSceneGraphPriority(listener1->clone(), sprite3);

    return true;
    }

    7月25日

    事件响应是写在HelloWorld类中的.cpp文件里面的init方法里面的

    1.首先判断是什么事件类型

    EventListenerPhysicsContact  //物理碰撞事件

    EventListenerTouchOneByOne  //单点触摸事件

    EventListenerTouchAllAtOnce  //多点触摸事件

    EventListenerAcceleration  //加速度计事件

    EventListenerKeyboard  //按键事件

    EventListenerMouse  //鼠标事件

    EventListenerCustom  //自定义事件

    2.创建出相应的事件监听器

    第一种:auto listener = EventListenerTouchOneByOne::create();

    第二种:在.h文件的属性定义里面定义EventListenerTouchOneByOne * listener;

    在.cpp文件的init方法里面写listener = EventListenerTouchOneByOne::create();

    3.设置事件监听器,结构是Lambda表达式,里面有一个回调函数,当被监听的对象满足事件监听器的要求时,执行回调函数里面的内容,this指的是当前层,Touch * t是用户的触摸各种属性, Event * e是事件类型。

    listener->onTouchBegan = [this](Touch * t, Event * e){

      for (auto it = this->gcs.begin(); it != this->gcs.end(); it++) {
        auto gc = *it;

        if (gc->getEdge()->getBoundingBox().containsPoint(t->getLocation())) {
        gc->onTouch();
        break;
        }
      }

      return false;

    };

    4.把事件监听器添加到事件分发器中,当用户触摸时,事件分发器就会将相应事件分发给相应的监听器进行响应,listener就是要添加的监听器,this指的是监听对象,就是当前层。

    Director::getInstance()->getEventDispatcher()->addEventListenerWithSceneGraphPriority(listener, this);

    注意:

    MOVED类型的鼠标点击事件,是把MOVED所对应的事件函数执行一遍,然后停留在执行完后的状态,直到ENDED类型的鼠标点击事件的函数被调用。

    case Widget::TouchEventType::MOVED:
    gamecontroller->onCreep();
    break;

    case Widget::TouchEventType::ENDED:
    gamecontroller->onNormal();
    break;

  • 相关阅读:
    【转】【金蝶K3Cloud】 分页账表
    【转】【金蝶K3Cloud】 树形账表
    【金蝶K3Cloud】Python拼接字段
    性能分析及调优
    性能测试指南
    性能测试--测试指标
    性能测试--术语解释
    BurpSuite 安装使用
    BeEF 安装使用
    win10与vmware 中的kali linux 共享文件夹
  • 原文地址:https://www.cnblogs.com/HangZhe/p/5474825.html
Copyright © 2020-2023  润新知