Кнопки Cocos2d-x - MenuItemSprite против кнопки

Cocos2d-x Версия 3.17

// Создать кнопку: Тип - 1

{
    Sprite *spr1 = Sprite::createWithSpriteFrameName(FRAME_MM_PLAY);
    Sprite *spr2 = Sprite::createWithSpriteFrameName(FRAME_MM_PLAY);

    spr2->setColor( Color3B(200, 200, 200) );

    auto *playButton = MenuItemSprite::create(spr1, spr2, CC_CALLBACK_1(CBirdMainMenu::playBtnPress, this));
    playButton->setScale(1.0f);
    playButton->setEnabled(true);

    auto playMenu = Menu::create(playButton, nullptr);
}

// Создать кнопку: Тип - 2

Button *infoButton
    {
        infoButton = Button::create(FRAME_MM_INFO,FRAME_MM_INFO,FRAME_MM_INFO,Widget::TextureResType::PLIST);
        infoButton->setZoomScale(0.2f);
        infoButton->setPressedActionEnabled(true);
        infoButton->addTouchEventListener([&](Ref* sender, cocos2d::ui::Widget::TouchEventType type){
            switch (type)
            {
                case ui::Widget::TouchEventType::BEGAN:
                    break;
                case ui::Widget::TouchEventType::ENDED:
                    this->infoButtonPress();
                    break;
                default:
                    break;
            }
        });

        This->addChild(infoButton, 2);
    }

В Type-2 как изменить цвет кнопки при нажатии. Я использовал одно изображение для всех состояний. Я не люблю использовать отдельные изображения. Можно ли изменить цвет выделенного спрайта в Type2? В Type1, для MenuItemSprite, мы можем легко установить цвет для выбранного изображения …… В Type-2, если я вызываю setColor для Button, он дает сбой.

infoButton->setColor(Color3B(200, 200, 200)); //Crashed on this

Не знаю, как изменить цвет кнопки при нажатии.

я не вижу в этом никаких проблем. предполагая, что FRAME_MM_X является массивом символов имен изображений, а изображение хранится в атласе текстуры, поскольку вы используете Widget::TextureResType::PLIST. Что за сбой, кстати?

Yucel_K 21.10.2018 02:10

Сбой @Yucel_K происходит только тогда, когда мы вызываем infoButton-> setColor ... в противном случае сбоя нет.

Guru 21.10.2018 18:52

вы пробовали изменить цвет сразу после инициализации кнопки? в моем cocos2dx все работает нормально. Я подозреваю, что, возможно, указатель infoButton станет недействительным до вызова setColor. какой сбой вы получите?

Yucel_K 21.10.2018 19:08

@Yucel_K вот скриншоты .. спасибо что искали. app.box.com/s/hefysv8c8nccpcz41piv0z5e6fkceiwc

Guru 21.10.2018 19:40

Можете ли вы показать мне, где вы инициализируете указатель toolbar? Думаю, я знаю, где он будет выпущен, но хочу убедиться.

Yucel_K 21.10.2018 21:21
Стоит ли изучать PHP в 2026-2027 годах?
Стоит ли изучать PHP в 2026-2027 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
2
5
600
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

вы создаете кнопку и назначаете ей указатель InfoButton.

infoButton = Button::create(FRAME_MM_INFO,FRAME_MM_INFO,FRAME_MM_INFO,Widget::TextureResType::PLIST);

проблема в том, что ваш infoButton является локальным указателем.

Button *infoButton;
  {
    ...
    ...

из предоставленного вами скриншота видно, что он создан локально в CBirdMenu::SetupMenu().

затем вы добавляете info button в качестве дочернего объекта к объекту, на который указывает указатель с именем toolBar. Однако в момент завершения CBirdMenu::SetupMenu() ваш infoButton больше не будет распознаваться лямбда-выражением.

один из способов и, возможно, самый простой способ решить вашу проблему - использовать динамическое приведение лямбда-параметра Ref* sender в лямбда-выражении.

InfoButton->addTouchEventListener([&](Ref* sender, cocos2d::ui::Widget::TouchEventType type)
{
    cocos2d::ui::Button * infButton = dynamic_cast<cocos2d::ui::Button*>(sender);
    if (infButton)//check if casting done properly
       infButton->setColor(Color3B(0, 200, 0)); //colour set to green.
});

или альтернативно, вместо того, чтобы иметь локальный указатель infoButton, сохранить его как член класса CBirdMenu. Таким образом, infoButton никогда не потеряется, пока существует cBirdMenu.

вот быстрая демонстрация. заголовочный файл;

    #include "cocos2d.h"
    #include "ui\CocosGUI.h"
    class HelloWorld : public cocos2d::Layer
    {
    public:
        static cocos2d::Scene* createScene();
        virtual bool init();
        void menuCloseCallback(cocos2d::Ref* pSender);
        CREATE_FUNC(HelloWorld);
    private:
        cocos2d::ui::Button * InfoButton; //member of HelloWorld.
    };

обратите внимание на частного члена cocos2d::ui::Button * InfoButton; И, наконец, исходный файл, в котором создается кнопка и назначается указателю infoButton.

// on "init" you need to initialize your instance
bool HelloWorld::init()
{
    //////////////////////////////
    // 1. super init first
    if ( !Layer::init() )
        return false;

    Size visibleSize = Director::getInstance()->getVisibleSize();
    Vec2 origin = Director::getInstance()->getVisibleOrigin();

    InfoButton = cocos2d::ui::Button::create("HelloWorld.png", "HelloWorld.png", "HelloWorld.png", ui::Widget::TextureResType::LOCAL);
    InfoButton->setColor(Color3B(255, 0, 0)); //colour is set to red as suppose to.
    InfoButton->setTitleFontSize(InfoButton->getTitleFontSize() * 0.7);
    InfoButton->setPosition(Vec2(visibleSize.width / 2 + origin.x, visibleSize.height / 2 + origin.y));
    InfoButton->addTouchEventListener([&](Ref* sender, cocos2d::ui::Widget::TouchEventType type)
    {
        InfoButton->setColor(Color3B(0, 200, 0)); //colour set to green.
    });
    // add the button as a child to this layer
    this->addChild(InfoButton, 2);
    return true;
}

Если вы примените тот же принцип к своему коду, это должно решить вашу текущую проблему с lambda. Однако я все еще не уверен, что делает ваш класс toolBar, поскольку он не включен в код. Если toolBar является настраиваемым классом, я рекомендую вам переместить ваш infoButton с CBirdMenu на toolBar, если вы выбираете второй подход для решения вашей проблемы.

Большое спасибо за ваш ответ ... оба решения сработали.

Guru 22.10.2018 07:52

Другие вопросы по теме