• cocos基础教程(12)点击交互的三种处理


    1、概述

    游戏也好,程序也好,只有能与用户交互才有意义。手机上的交互大致可以分为两部分:点击和输入。其中点击更为重要,几乎是游戏中全部的交互。在Cocos2d-x 3.0中,更改了dispatch机制。同时加入了两种新的交互形式:listener 和touchEvent回调。加上先前版本中的点击函数回调,与重写layer层的touch消息响应,构成了一个相对完整的交互模式。

    2、三种点击

    1、函数回调

    函数回调是最简单的响应形式,一直以来被用于MenuItem中的点击处理。在新版本中,此处发生了些小改变。我们可以看到在生成的程序中相关代码是这样的:
    // a selector callback  
    void menuCloseCallback(Object* pSender);  
      
    auto closeItem = MenuItemImage::create("CloseNormal.png","CloseSelected.png",  
                            CC_CALLBACK_1(HelloWorld::menuCloseCallback, this));  
      
    void HelloWorld::menuCloseCallback(Object* pSender)  
    {  
        Director::getInstance()->end();  
      
    #if (CC_TARGET_PLATFORM == CC_PLATFORM_IOS)  
        exit(0);  
    #endif  
    }  

    其中CC_CALLBACK_1宏是将函数与对象绑定在一起,1表示这个函数有一个参数。当点击这个按钮时,会调用这个回调函数。

        除了基于c++11的这个形式的改变,使用方法与先前相同

    2、TouchEvent响应

        这是新加入的响应方式。它主要是使用在Widget上的。可以将其看做是函数回调的一个扩展,为更多的响应处理提供可能。使用方法大致是:
    //声明  
    void touchButton(Object* object,TouchEventType type);  
      
    //挂接到控件上  
    uiButton->addTouchEventListener(this,toucheventselector(HelloWorld::touchButton));  
      
    //实现  
    void HelloWorld::touchButton(Object* object,TouchEventType type)  
    {  
        LabelTTF* label;  
        switch (type)  
        {  
        case TouchEventType::TOUCH_EVENT_BEGAN:  
            label = static_cast<LabelTTF*>(getChildByTag(11));  
            label->setString("按下按钮");  
            break;  
        case TouchEventType::TOUCH_EVENT_MOVED:  
            label = static_cast<LabelTTF*>(getChildByTag(11));  
            label->setString("按下按钮移动");  
            break;  
        case TouchEventType::TOUCH_EVENT_ENDED:  
            label = static_cast<LabelTTF*>(getChildByTag(11));  
            label->setString("放开按钮");  
            break;  
        case TouchEventType::TOUCH_EVENT_CANCELED:  
            label = static_cast<LabelTTF*>(getChildByTag(11));  
            label->setString("取消点击");  
            break;  
        default:  
            break;  
        }  
    } 

    通常作为UI的Widget都会在最上层,所以可以“基本上”认为这种使用方式会优先于其他方式处理点击消息。因为UILayer也会有层级的改变,比如它和MenuItem之间的关系。所以说“基本上”。

    3、Listener消息响应方式

        这种实现也是新加入的。它更像是点击的一个层次过滤器。点击时,在listener队里中进行过滤。每一个listener检查自己保存的touch消息响应是否会被触发。一层一层过滤,最后在到Layer的touch消息响应。

    它被设计成一个全局点击响应控制。具体的用法大致是这样:

    auto dispatcher = Director::getInstance()->getEventDispatcher();  
    auto myListener = EventListenerTouchOneByOne::create();  
      
    //如果不加入此句消息依旧会向下传递  
    myListener->setSwallowTouches(true);  
      
    myListener->onTouchBegan = [=](Touch* touch,Event* event)  
    {  
        //some check  
        if (pass)  
        {  
            return true;  
        }  
        return false;  
    };  
      
    myListener->onTouchMoved = [=](Touch* touch,Event* event)  
    {  
        //do something  
    };  
      
    myListener->onTouchEnded = [=](Touch* touch,Event* event)  
    {  
        //do something  
    };  
      
    dispatcher->addEventListenerWithSceneGraphPriority(myListener,mySprite1);  
    dispatcher->addEventListenerWithSceneGraphPriority(myListener,mySprite2);  

    其原理是在dispatcher中检查listener列表,例如myListener或加进来的其他listener。然后每个listener检查自己中的Item看能否达到检查条件,例如:mySprite1,mySprite2。然后执行相应的操作。但这样的话,当控件很多的时候,每一次事件都进行这种双链表的检查操作不知会不会影响些性能?

  • 相关阅读:
    import 本地Python module或package
    JSON+YAML初步学习+ciscoconfparse
    Ansible用于网络设备管理 part 4 使用NAPALM成品库+Gabriele的方法+循环
    Community Value再理解
    职业素养-8S
    JavaWeb项目的数据库访问简单基础类
    FastJson+Servlet实现Ajax案例
    Echarts和JSTL、EL标签的混合使用
    大数据典型应用场景
    Web前端开发与设计13-购物车案例
  • 原文地址:https://www.cnblogs.com/damowang/p/4831919.html
Copyright © 2020-2023  润新知