Cocos2d-x 事件分发机制

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

新事件分发机制

新事件分发机制:在新的事件分发机制中,只需通过创建一个事件监听器-用来实现各种触发后的逻辑,然后添加到事件分发器_eventDispatcher,所有事件监听器有这个分发器统一管理,即可完成事件响应。

事件监听器有以下几种:

  • 触摸事件 (EventListenerTouch)
  • 键盘响应事件 (EventListenerKeyboard)
  • 鼠标响应事件 (EventListenerMouse)
  • 自定义事件 (EventListenerCustom)
  • 加速记录事件 (EventListenerAcceleration)

_eventDispatcher的工作由三部分组成:

  • 事件分发器 EventDispatcher
  • 事件类型 EventTouch,EventKeyboard 等
  • 事件监听器 EventListenerTouch,EventListenerKeyboard 等

监听器实现了各种触发后的逻辑,在适当时候由事件分发器分发事件类型,然后调用相应类型的监听器。

用户输入事件

触摸事件

在3.0中,只需创建多点触摸事件监听器,并将其添加到事件分发器中即可。

以下代码在一个界面中添加三个按钮,三个按钮相互遮挡,并且都能触发触摸事件:

// 创建按钮精灵
    auto sprite1 = Sprite::create("Images/CyanSquare.png");
    sprite1->setPosition(origin+Point(size.width/2,size.height/2) + Point(-80,80));
    addChild(sprite1,10);
    // sprite2
    ...
    // sprite3
    ...

创建好按钮精灵后,创建单点触摸事件监听器,并完成相应逻辑处理

// 创建一个事件监听器类型为 OneByOne 的单点触摸
    auto listener1 = EventListenerTouchOneByOne::create();
    // 设置是否吞没事件,在 onTouchBegan 方法返回 true 时吞没
    listener1->setSwallowTouches(true);

    // 使用 lambda 实现 onTouchBegan 事件回调函数
    listener1->onTouchBegan = [](Touch* touch,Event* event){
        // 获取事件所绑定的 target 
        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("sprite began... x = %f,y = %f",locationInNode.x,locationInNode.y);
            target->setOpacity(180);
            return true;
        }
        return false;
        };

    // 触摸移动时触发
    listener1->onTouchMoved = [](Touch* touch,Event* event){...};

    // 点击事件结束处理
    listener1->onTouchEnded = [=](Touch* touch,Event* event){...};

最后需要将事件监听器添加到事件分发器

// 添加监听器
    _eventDispatcher->addEventListenerWithSceneGraPHPriority(listener1,sprite1);
    _eventDispatcher->addEventListenerWithSceneGraPHPriority(listener1->clone(),sprite2);
    _eventDispatcher->addEventListenerWithSceneGraPHPriority(listener1->clone(),sprite3);

以上代码_eventDispatcher是Node的属性,通过它管理当前节点(场景、层、精灵等)的所有事件的分发。

我们可以通过以下方法移除一个已经被添加了的监听器。

_eventDispatcher->removeEventListener(listener);

也可以使用如下方法,移除当前事件分发器中所有监听器。

_eventDispatcher->removeAllEventListeners();

键盘响应事件

键盘响应事件和处理触摸事件使用了相同的处理方式,一下代码演示如何处理键盘响应事件:

// 初始化并绑定
    auto listener = EventListenerKeyboard::create();
    listener->onKeyPressed = CC_CALLBACK_2(KeyboardTest::onKeyPressed,this);
    listener->onKeyReleased = CC_CALLBACK_2(KeyboardTest::onKeyReleased,this);

    _eventDispatcher->addEventListenerWithSceneGraPHPriority(listener,this);

    // 键位响应函数原型
    void KeyboardTest::onKeyPressed(EventKeyboard::KeyCode keyCode,Event* event)
    {
        log("Key with keycode %d pressed",keyCode);
    }

    void KeyboardTest::onKeyReleased(EventKeyboard::KeyCode keyCode,Event* event)
    {
        log("Key with keycode %d released",keyCode);
    }

鼠标响应事件

下面代码实现鼠标响应事件的实现步骤:

// 创建监听器
    _mouseListener = EventListenerMouse::create();

    // 时间响应逻辑
    _mouseListener->onMouseMove = [=](Event *event){
    EventMouse* e = (EventMouse*)event;
    string str = "Mouse Down detected,Key: ";
    str += tostr(e->getMouseButton());
    // ...
};
    _mouseListener->onMouseUp = [=](Event *event){...};
    _mouseListener->onMouseDown = [=](Event *event){...};
    _mouseListener->onMouseScroll = [=](Event *event){...};
    // 添加到事件分发器
    _eventDispatcher->addEventListenerWithSceneGraPHPriority(_mouseListener,this);

自定义事件

以上是系统自带的事件类型,事件由系统内部自动触发,如 触摸屏幕,键盘响应等,除此之外,还提供了一种 自定义事件,简而言之,它不是由系统自动触发,而是人为的干涉,如下:

_listener = EventListenerCustom::create("game_custom_event1",[=](EventCustom* event){
        std::string str("Custom event 1 received,");
        char* buf = static_cast<char*>(event->getUserData());
        str += buf;
        str += " times";
        statusLabel->setString(str.c_str());
    });

    _eventDispatcher->addEventListenerWithFixedPriority(_listener,1);

以上定义了一个 “自定义事件监听器”,实现了相关逻辑,并且添加到事件分发器。上面的自定义事件将由以下代码触发:

static int count = 0;
    ++count;
    char* buf = new char[10];
    sprintf(buf,"%d",count);
    EventCustom event("game_custom_event1");
    event.setUserData(buf);
    if(...)
    {
        _eventDispatcher->dispatchEvent(&event);
    }
    CC_SAFE_DELETE_ARRAY(buf);

定义一个 EventCustom,并且设置了其 UserData 数据,手动的通过 _eventDispatcher->dispatchEvent(&event); 将此事件分发出去,从而触发之前所实现的逻辑。

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