Touch Priority, Multiple Layers

How can touch priority be set in v3.8 JS?
I older versions, you could use “setTouchPriority”.

Currently, I have several layers. Each layer has an event listener. I want the layers “on top” to swallow the event.
event: cc.EventListener.TOUCH_ALL_AT_ONCE, swallowTouches: true,

How can I set the priority, such that only the top layer will get the event?

Thank you.

http://cocos2d-x.org/docs/manual/framework/html5/v3/eventManager/en

I think touch priority is set when adding the event listener to the event manager. e.g.

cc.eventManager.addListener(listener, layer);

Pretty sure this sets the order in which touch is received based on the order things appear on screen, with things on top getting touch first.

It is possible to add touch listeners with fixed priority as well, i.e. you choose the order they receive touch.

1 Like

Hi
Can someone tell me what swallowTouches does that do exactly? Is it true by default? What happens when it’s true/false?

Thanks!

1 Like

To put it simply, if you have multiple EventListenerTouchOneByOne event listeners in your scene, setting setSwallowTouches to true for each means only the first one that returns true from onTouchBegan will get calls to onTouchMoved and onTouchEnded for that touch. I think it is set to false by default.

When you touch the screen, the event dispatcher will call the onTouchBegan function of each EventListenerTouchOneByOne. Each event listener that returns true from onTouchBegan will also get calls to onTouchMoved and onTouchEnded for that touch.

If swallowTouches is set to true for an EventListenerTouchOneByOne, if it returns true from onTouchBegan then no other event listener after it will get the call to onTouchBegan and so they won’t get calls to onTouchMoved or onTouchEnded either.

Thanks for that detailed explanation. But could you give me an example of when (and why) someone would use more than one EventListenerTouchOneByOne event listener in the same scene?

Say for example my game is a racing game and the user can touch anywhere on the left side of the screen to turn left and anyone on the right side of the screen to turn right. How would you go about handling these touches?

Thanks in advance @grimfate

You might use one event listener for the UI and one for controlling the game. You wouldn’t want the game to steer your car when you are touching something in the UI. So the UI would get the event first and would “swallow” the touch so it doesn’t get passed to the game controls listener as well.

Awesome thanks for the reply!
So I have a UI button like this

var closeButton = new ccui.Button();
closeButton.loadTextures(res.closeBtn_n_png, res.closeBtn_s_png);
closeButton.addTouchEventListener(this.onClose, this);

Where and how would I make this swallowTouches? I’m not sure what the syntax is exactly.
Thanks a lot! Much appreciated :smile:

I am not sure, sorry. I haven’t used Cocos’s buttons. I would assume they have swallowTouches set to true already.

Awesome, thanks for the response man.
Awesome beard too.

@grimfate @efares Widget and widget derivatives swallow implicitly:

UIWidget.cpp: 570

void Widget::setTouchEnabled(bool enable)
{
    if (enable == _touchEnabled)
    {
        return;
    }
    _touchEnabled = enable;
    if (_touchEnabled)
    {
        _touchListener = EventListenerTouchOneByOne::create();
        CC_SAFE_RETAIN(_touchListener);
        _touchListener->setSwallowTouches(true);
        _touchListener->onTouchBegan = CC_CALLBACK_2(Widget::onTouchBegan, this);
        _touchListener->onTouchMoved = CC_CALLBACK_2(Widget::onTouchMoved, this);
        _touchListener->onTouchEnded = CC_CALLBACK_2(Widget::onTouchEnded, this);
        _touchListener->onTouchCancelled = CC_CALLBACK_2(Widget::onTouchCancelled, this);
        _eventDispatcher->addEventListenerWithSceneGraphPriority(_touchListener, this);
    }
    else
    {
        _eventDispatcher->removeEventListener(_touchListener);
        CC_SAFE_RELEASE_NULL(_touchListener);
    }
}