有關按鈕的觸摸優先級和layer的觸摸事件衝突問題

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

發佈了28 篇原創文章 · 獲贊 10 · 訪問量 2萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章