我在MainScene.lua的构造函数里创建了一个图片,代码如下:
self.node_ = display.newScale9Sprite("Button01.png", display.cx, display.cy, cc.size(500, 400), cc.rect(10, 10, 30, 30))
self.node_:retain()
self.node_:setNodeEventEnabled(true, function(evt)
local name = evt.name
if name == "enter" then
self.node_:setTouchEnabled(true)
self.node_:addNodeEventListener(cc.NODE_TOUCH_EVENT, function(evt)
print(evt.name)
end)
end
end)
点击该图片会输出点击事件
我创建了该图片没有马上添加到场景上面,而是retain了
然后我在场景上面添加了一个按钮,用来控制上面的图片在场景上面的添加和删除
就是如果图片没被添加到场景时执行:
self.node_:addTo(self)
图片已经在场景时执行:
self.node_:removeSelf()
第一次点击按钮,图片被添加到场景上,点击图片,能正常输出点击事件
再点击按钮,图片从场景上移除
问题来了:再点击按钮,图片重新添加到场景, 点击图片,不输出点击事件了,这是为什么?
===================结贴=================
找到原因了,看看CCNode.cpp的cleanup函数和setTouchEnabled函数
void Node::cleanup()
{
// actions
this->stopAllActions();
this->unscheduleAllSelectors();
#if CC_ENABLE_SCRIPT_BINDING
if (_keyboardListener) {
_eventDispatcher->removeEventListener(_keyboardListener);
_keyboardListener = nullptr;
}
if (_accelerationListener) {
_eventDispatcher->removeEventListener(_accelerationListener);
_accelerationListener = nullptr;
}
if (_scriptEventDispatcher->hasScriptEventListener(NODE_EVENT))
{
ScriptEngineManager::getInstance()->getScriptEngine()->executeNodeEvent(this, kNodeOnCleanup);
}
#endif // #if CC_ENABLE_SCRIPT_BINDING
if (isTouchEnabled()) {
unregisterWithTouchDispatcher();
}
// timers
for( const auto &child: _children)
child->cleanup();
}
void Node::setTouchEnabled(bool enabled)
{
if (m_bTouchEnabled != enabled)
{
m_bTouchEnabled = enabled;
//if (_running)
{
if (enabled)
{
registerWithTouchDispatcher();
}
else
{
unregisterWithTouchDispatcher();
}
}
}
}
红字部分直接运行unregisterWithTouchDispatcher()来让对象触摸失效,跟setTouchEnabled(false)的区别就在于有没将m_bTouchEnabled设为false
当对象重新添加到场景时执行setTouchEnabled(true),函数发现m_bTouchEnabled还是为true,所以就没让对象触摸生效了
为什么cleanup函数里要用unregisterWithTouchDispatcher()而不用setTouchEnabled(false)呢??
原来的代码改为这样就可以运行:
self.node_ = display.newScale9Sprite(“Button01.png”, display.cx, display.cy, cc.size(500, 400), cc.rect(20, 20, 48, 38))
self.node_:retain()
self.node_:addNodeEventListener(cc.NODE_TOUCH_EVENT, function(evt)
print(evt.name)
end)
self.node_:setNodeEventEnabled(true, function(evt)
local name = evt.name
if name == “enter” then
self.node_:setTouchEnabled(true)
elseif name == “exit” then
self.node_:setTouchEnabled(false)
end
end)