【问题标题】:Why isn't touch listener removed when Sprite is removed?为什么当 Sprite 被移除时触摸监听器没有被移除?
【发布时间】:2016-01-19 11:35:51
【问题描述】:

我有以下代码用于检查精灵的触摸:

void SpriteBlock::addEvents()
{
auto listener = cocos2d::EventListenerTouchOneByOne::create();
listener->setSwallowTouches(true);

listener->onTouchBegan = [&](cocos2d::Touch* touch, cocos2d::Event* event)
{
    Vec2 p = touch->getLocation();
    Rect rect = this->getBoundingBox();

    if(rect.containsPoint(p))
    {
        return true; // to indicate that we have consumed it.
    }

    return false; // we did not consume this event, pass thru.
};

listener->onTouchEnded = [=](cocos2d::Touch* touch, cocos2d::Event* event)
{
    SpriteBlock::touchEvent(touch);
};

cocos2d::Director::getInstance()->getEventDispatcher()->addEventListenerWithFixedPriority(listener, 30);
}


void SpriteBlock::touchEvent(cocos2d::Touch* touch)
{
}

这似乎工作正常,但即使在精灵被销毁后,它仍然会被触发(如果我点击精灵存在的最后一个地方),它会崩溃:

"

线程 1:EXC_BAD_ACCESS(代码=2,地址=0x7....)

"

在以下行:

    Rect rect = this->getBoundingBox();

现在我似乎很清楚 sprite 已被销毁,因为我的析构函数设置为在触发时显示日志消息(确实如此):

SpriteBlock::~SpriteBlock() {
    CCLOG("Block destroyed"); 
}

那么这里的问题是什么?为什么听者没有被我的精灵摧毁?我通过执行以下操作来销毁我的精灵:

    mysprite->removeFromParent();

当我创建精灵时,我不存储任何引用。我只是将它添加到场景的主层,所以它不应该保留。我使用以下方法创建它:

SpriteBlock *block = SpriteBlock::create();

当精灵被移除时,如何确保触摸监听器也被移除?

【问题讨论】:

    标签: cocos2d-x cocos2d-x-3.0


    【解决方案1】:
    auto listener = cocos2d::EventListenerTouchOneByOne::create();
    

    将其作为变量存储在 SpriteBlock 类中。

    然后在 SpriteBlock 析构函数中移除一个监听器。

    【讨论】:

    • 对 - 它在 cocos2d 网站的不同页面上有所提及,但在解释如何使用监听器的文章中并不明显。显然有些类型的监听器会被自动移除,但是像这样的类型需要被显式移除。
    • @Makalele 你能描述更多关于如何在析构函数中删除监听器的信息吗?
    • cocos2d::Director::getInstance()->getEventDispatcher()->removeEventListener(listener);
    猜你喜欢
    • 1970-01-01
    • 2018-06-20
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-02-16
    • 1970-01-01
    相关资源
    最近更新 更多