自己在做到有關按鈕的點擊事件和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);這樣添加了