自己在做到有关按钮的点击事件和layer的touch事件问题上也是让自己头疼了好一阵,也尝试过几种方式
(1)// _eventDispatcher->addEventListenerWithFixedPriority(listner, -128);这个方式不建议采用,你如果这样注册了你稍不留神 可能就会出现问题
(2)_eventDispatcher->addEventListenerWithSceneGraphPriority(listner, this);这种方式是推荐使用的,可是这样大家都知道按钮的优先级是比layer的touch事件的优先级要高的,所以我就这种情况作了一些修改。
我自己重写了menu类当然是自己的menu类。
class ZYMenuOnly : public cocos2d::Menu
{
public:
ZYMenuOnly();
virtual ~ZYMenuOnly();
static ZYMenuOnly* create();
#if (CC_TARGET_PLATFORM == CC_PLATFORM_WP8) || (CC_TARGET_PLATFORM == CC_PLATFORM_WINRT)
// WP8 in VS2012 does not support nullptr in variable args lists and variadic templates are also not supported
typedef ZYMenuOnly* M;
static ZYMenuOnly* create(M m1, std::nullptr_t listEnd) { return variadicCreate(m1, NULL); }
static ZYMenuOnly* create(M m1, M m2, std::nullptr_t listEnd) { return variadicCreate(m1, m2, NULL); }
static ZYMenuOnly* create(M m1, M m2, M m3, std::nullptr_t listEnd) { return variadicCreate(m1, m2, m3, NULL); }
static ZYMenuOnly* create(M m1, M m2, M m3, M m4, std::nullptr_t listEnd) { return variadicCreate(m1, m2, m3, m4, NULL); }
static ZYMenuOnly* create(M m1, M m2, M m3, M m4, M m5, std::nullptr_t listEnd) { return variadicCreate(m1, m2, m3, m4, m5, NULL); }
static ZYMenuOnly* create(M m1, M m2, M m3, M m4, M m5, M m6, std::nullptr_t listEnd) { return variadicCreate(m1, m2, m3, m4, m5, m6, NULL); }
static ZYMenuOnly* create(M m1, M m2, M m3, M m4, M m5, M m6, M m7, std::nullptr_t listEnd) { return variadicCreate(m1, m2, m3, m4, m5, m6, m7, NULL); }
static ZYMenuOnly* create(M m1, M m2, M m3, M m4, M m5, M m6, M m7, M m8, std::nullptr_t listEnd) { return variadicCreate(m1, m2, m3, m4, m5, m6, m7, m8, NULL); }
static ZYMenuOnly* create(M m1, M m2, M m3, M m4, M m5, M m6, M m7, M m8, M m9, std::nullptr_t listEnd) { return variadicCreate(m1, m2, m3, m4, m5, m6, m7, m8, m9, NULL); }
static ZYMenuOnly* create(M m1, M m2, M m3, M m4, M m5, M m6, M m7, M m8, M m9, M m10, std::nullptr_t listEnd) { return variadicCreate(m1, m2, m3, m4, m5, m6, m7, m8, m9, m10, NULL); }
// On WP8 for lists longer than 10 items, use createWithArray or variadicCreate with NULL as the last argument
static ZYMenuOnly* variadicCreate(MenuItem* item, ...);
#else
/** creates a Menu with MenuItem objects */
static ZYMenuOnly* create(MenuItem* item, ...) CC_REQUIRES_NULL_TERMINATION;
#endif
static ZYMenuOnly* createWithItem(MenuItem* item);
/** creates a Menu with MenuItem objects */
static ZYMenuOnly* createWithItems(MenuItem *firstItem, va_list args);
......
}
大家看到这其实发现和menu类没有什么区别,的确是没有什么区别,区别在在方法的实现上
bool ZYMenuOnly::initWithArray(const Vector<MenuItem*>& arrayOfItems)
{
if (!Layer::init())
{
return false;
}
_enabled = true;
// menu in the center of the screen
Size s = Director::getInstance()->getWinSize();
this->ignoreAnchorPointForPosition(true);
setAnchorPoint(Vec2(0.5f, 0.5f));
this->setContentSize(s);
setPosition(Vec2(s.width / 2, s.height / 2));
int z = 0;
for (auto& item : arrayOfItems)
{
this->addChild(item, z);
z++;
}
_selectedItem = nullptr;
_state = Menu::State::WAITING;
// enable cascade color and opacity on menus
setCascadeColorEnabled(true);
setCascadeOpacityEnabled(true);
auto touchListener = EventListenerTouchOneByOne::create();
touchListener->setSwallowTouches(false);
touchListener->onTouchBegan = CC_CALLBACK_2(ZYMenuOnly::onTouchBegan, this);
touchListener->onTouchMoved = CC_CALLBACK_2(ZYMenuOnly::onTouchMoved, this);
touchListener->onTouchEnded = CC_CALLBACK_2(ZYMenuOnly::onTouchEnded, this);
touchListener->onTouchCancelled = CC_CALLBACK_2(ZYMenuOnly::onTouchCancelled, this);
_eventDispatcher->addEventListenerWithSceneGraphPriority(touchListener, this);
return true;
}
第一点区别是在红色区域的地方,这个地方是没有吞噬触摸的,然后在touchBegin的方法里你让menu的点集事件传下去就是了。其实就是这么简单,我目前没觉得这么写会造成什么不好的影响,希望对你有用。
然后你在自己建立的layer中创建监听的时候就可以_eventDispatcher->addEventListenerWithSceneGraphPriority(listner, this);这样添加了