0

I have a ui::ScrollView containing a number of sprites.

I have created each sprite and added a touch listener to each sprite by doing something like:

for(int i=0; i < 5; i++){
    Sprite* foo = Sprite::createWithSpriteFrameName("foo");
    myScrollView->addChild(foo);

    auto listener = EventListenerTouchOneByOne::create();
    listener->onTouchBegan = [this,somestring](Touch* touch, Event* event){
        ......some code
    };
    listener->onTouchMoved = [foo,this,somestring](Touch* touch, Event* event){
        ......some code
    };
    listener->onTouchEnded = [foo,this,somestring](Touch* touch, Event* event){
        ......some code
    };
 foo->getEventDispatcher->addEventListenerWithSceneGraphPriority(listener1,foo);
}

The problem is, if I click ANYWHERE on screen, it seems to trigger the touch events of ALL the sprites created in the loop. Is there something incorrect in how I am creating the listener, or does it have to do with some conflict with touches in a ui::ScrollView ?

I am using v 3.10

Rahul Iyer
  • 19,924
  • 21
  • 96
  • 190

2 Answers2

0

Because that is how TouchListener works in cocos2d-x. All touch listener will be called unless someone has swallowed the touch event. Your code would be:

auto touchSwallower = EventListenerTouchOneByOne::create();
touchSwallower ->setSwallowed(true);
touchSwallower->onTouchBegan = [](){ return true;};
getEventDispatcher->addEventListenerWithSceneGraphPriority(touchSwallower ,scrollview);


for(int i=0; i < 5; i++){
    Sprite* foo = Sprite::createWithSpriteFrameName("foo");
    myScrollView->addChild(foo);

    auto listener = EventListenerTouchOneByOne::create();
    listener->setSwallowed(true);
    listener->onTouchBegan = [this,somestring](Touch* touch, Event* event){
        ......some code
       Vec2 touchPos = myScrollView->convertTouchToNodeSpace(touch);
       return foo->getBoundingBox()->containsPoint(touchPos);
    };
    listener->onTouchMoved = [foo,this,somestring](Touch* touch, Event* event){
        ......some code
    };
    listener->onTouchEnded = [foo,this,somestring](Touch* touch, Event* event){
        ......some code
    };
 foo->getEventDispatcher->addEventListenerWithSceneGraphPriority(listener1,foo);
}
Zen
  • 5,065
  • 8
  • 29
  • 49
0

cocos2dx will dispatch the touch-event to every Node attached a touch-event, unless someone swallow the it.

But if you want the "node" default judge whether touch-location in the content, try to use "UIWidget" with "addTouchEventListener". It will calculate by itself.

bool Widget::onTouchBegan(Touch *touch, Event *unusedEvent)
{
    _hitted = false;
    if (isVisible() && isEnabled() && isAncestorsEnabled() && isAncestorsVisible(this) )
    {
        _touchBeganPosition = touch->getLocation();
        auto camera = Camera::getVisitingCamera();
        if(hitTest(_touchBeganPosition, camera, nullptr))
        {
            if (isClippingParentContainsPoint(_touchBeganPosition)) {
                _hittedByCamera = camera;
                _hitted = true;
            }
        }
    }
    if (!_hitted)
    {
        return false;
    }
    setHighlighted(true);

    /*
     * Propagate touch events to its parents
     */
    if (_propagateTouchEvents)
    {
        this->propagateTouchEvent(TouchEventType::BEGAN, this, touch);
    }

    pushDownEvent();
    return true;
}
Richard
  • 35
  • 1
  • 4