[Cocos2d-x] How to add different touch event listener to button in loop

Hi All,

I am using loop to create 0 - 100 buttons in my game. And, I wish these buttons will call to different method.

For example:
First button for unfriending “David”
Second button for unfriending “Joe”
… so on.

I tried to use array to store the buttons and set the touch event listener to each button in the array. I also tried to simply add touch event listener to the button. But both cases result in bad access error, when I pressed the button.

for (i = 0 ; i < numOfFd; i++) // 4,Joe,JL,0,Ivan,IS,0,NEO,NY,0,Nic,NN,0
    {
        waitApply = Sprite::create("testlist##.png");
        Label* fdID = Label::createWithTTF(b[i], "NotoSansCJKtc-Regular.otf", 50);
        fdID->setPosition(Vec2(350,130));
        waitApply->addChild(fdID, 0);
        Label* fdName = Label::createWithTTF(a[i], "NotoSansCJKtc-Regular.otf", 50);
        fdName->setPosition(Vec2(350,60));
        waitApply->addChild(fdName, 0);
        cocos2d::ui::Button* waitApplyFd = cocos2d::ui::Button::create("eye.png","eye.png");
        waitApplyFd->setPosition(Vec2(900,90));
        waitApplyFd->addTouchEventListener([&](Ref* sender, cocos2d::ui::Widget::TouchEventType type)
        {
            switch(type)
            {
                case cocos2d::ui::Widget::TouchEventType::BEGAN: break;
                case cocos2d::ui::Widget::TouchEventType::MOVED: break;
                case cocos2d::ui::Widget::TouchEventType::ENDED:
                    ApplyFd::deleteFd(userIDApply, i);
                    break;
                case cocos2d::ui::Widget::TouchEventType::CANCELED: break;
                default:
                    break;
            }
        });
        waitApply->addChild(waitApplyFd, 0);
        
        if(numOfFd >= 10)
        {
            waitApply->setPosition(Vec2(scrollView->getContentSize().width / 2, waitApply->getContentSize().height * numOfFd - (waitApply->getContentSize().height * i)));
        }else
        {
            waitApply->setPosition(Vec2(scrollView->getContentSize().width / 2, scrollView->getContentSize().height - (waitApply->getContentSize().height * i)));
            
        }
        scrollView->addChild(waitApply);
       
    }

Thank you for the help.

Hi,

What is the bad access error on?
Also, in this case, ‘i’ will always be the final index or numOfFd - 1.
You will likely need to add a variable onto the button itself. In this case, it would be easy to use the built in tag integer. waitApplyFd->setTag(i); somewhere in the loop. Then:
ApplyFd::deleteFd(userIDApply, ((cocos2d::ui::Button*)sender)->getTag());

I am not sure about all the other variables as the snippet you posted is a bit out of context…

2 Likes

As tdebock pointed out, the variable i will be the last value in the loop for all calls to that touch event listener, since you’re capturing the variable by reference, not by value.

An alternative fix to what tdeblock suggested is to capture i by value, like this:

waitApplyFd->addTouchEventListener([&, i](Ref* sender, cocos2d::ui::Widget::TouchEventType type)

If you’re unsure how this all works, then you perhaps brushing up on C++ lambdas will be of benefit to you: https://en.cppreference.com/w/cpp/language/lambda

2 Likes

This topic was automatically closed 24 hours after the last reply. New replies are no longer allowed.

Hi @tdebock,
I already fixed the problem by your solution.
Many thanks for the helping!!

1 Like