cocos2d-x 3.X 製作新手引導的按下事件
在新手引導的過程中,我們往往會強制使用者執行指定區域的操作。那麼一般的操作我們是在原有的介面上增加一個遮罩層,指定區域內可以向下傳遞touch事件。而其他區域則吸收掉點選事件。在cocos2d-x 3.x中的簡單實現方式如下。
1.首先我們建立一個主要介面,裡面有一些選單按鈕
主要內容程式碼如下:
void MainLayer::initView()//初始化顯示的方法
{
log("init MainLayer view");
std::vector<std::string> vec;
vec.push_back("開始");
vec.push_back("
vec.push_back("退出");
int i = 0;
double startX = VisibleRect::center().x;
double startY = VisibleRect::center().y + 100;
for (auto& title : vec)
{
//這裡只是簡單放三個按鈕。standardButtonWithTitle是自己實現的初始化ControlButton
ControlButton *button = standardButtonWithTitle(title.c_str());
//button->setAdjustBackgroundImage(false);
button->setPosition(Point (startX,startY- button->getContentSize().height / 2));
button->getBackgroundSpriteForState(Control::State::NORMAL)->setColor(Color3B(0,255,0));
button->getBackgroundSpriteForState(Control::State::HIGH_LIGHTED)->
addChild(button);
button->setTag(i);
button->addTargetWithActionForControlEvents(this, cccontrol_selector(LoginLayer::touchUpInsideAction), Control::EventType::TOUCH_UP_INSIDE);
startY -= (button->getContentSize().height + 30);
++i;
}
auto listener1 = EventListenerTouchOneByOne::create();
//swallow是吞嚥的意思. 代表本layer會吸收掉touch事件不向下層layer傳遞
listener1->setSwallowTouches(true);
listener1->onTouchBegan = [](Touch* touch, Event* event){
return true;
};
listener1->onTouchBegan = CC_CALLBACK_2(LoginLayer::layerTouch, this);
_eventDispatcher->addEventListenerWithSceneGraphPriority(listener1, this);
}
2.然後我們增加一個新的YinDaoLayer 它放在MainLayer的parent(為一個Scene)中,z值大於MainLayer.這裡也是設計的一個方面,所有的Layer都放在同一個scene中,並進行統一管理
void YinDaoLayer::initView()//初始化顯示的方法
{
log("init YinDaoLayer view");
//引導介面上可以點選的一個圖片,設定它的意義只是為了能夠向下傳遞touch事件
auto pSprite = CCSprite::create("qiyu.png");
pSprite->setPosition(VisibleRect::center() + Point(rand()%100,50));
pSprite->setTag(100);
addChild(pSprite);
//layer的按鍵監聽事件,一樣設定為吸收向下傳遞事件
auto listener1 = EventListenerTouchOneByOne::create();
listener1->setSwallowTouches(true);
listener1->onTouchBegan = [=](Touch* touch, Event* event){
Point locationInNode = pSprite->convertToNodeSpace(touch->getLocation());
Size s = pSprite->getContentSize();
Rect rect = Rect(0, 0, s.width, s.height);
//這裡是重點
//我們設定在點選到圖片的區域的時候本層不做事件處理.因為return true.則本層會做事件吸收,不會向下傳遞了
if (rect.containsPoint(locationInNode)) {
return false;
}
return true;
};
_eventDispatcher->addEventListenerWithSceneGraphPriority(listener1, this);
//設定sprite的touch事件
auto listener2 = EventListenerTouchOneByOne::create();
//注意 它並沒有吞嚥touch事件 代表點選這個按鈕的時候可以向下傳遞事件
listener2->onTouchBegan = [](Touch* touch, Event* event){
auto target = static_cast<Sprite*>(event->getCurrentTarget());
//Get the position of the current point relative to the button
Point locationInNode = target->convertToNodeSpace(touch->getLocation());
Size s = target->getContentSize();
Rect rect = Rect(0, 0, s.width, s.height);
//Check the click area
//點選區域在圖片區域內時 代表可以執行圖片的touch事件。
if (rect.containsPoint(locationInNode))
{
log("sprite began... x = %f, y = %f", locationInNode.x, locationInNode.y);
target->setOpacity(180);
return true;
}
return false;
};
listener2->onTouchEnded = [=](Touch* touch, Event* event){
auto target = static_cast<Sprite*>(event->getCurrentTarget());
log("sprite onTouchesEnded.. ");
target->setOpacity(255);
Point locationInNode = target->convertToNodeSpace(touch->getLocation());
Size s = target->getContentSize();
Rect rect = Rect(0, 0, s.width, s.height);
//Check the click area
if (rect.containsPoint(locationInNode))
{
//執行圖片按下去後的操作
}
};
_eventDispatcher->addEventListenerWithSceneGraphPriority(listener2, pSprite);
}
按照上面的做完後可以發現 按下圖片的同時可以觸發下層按鈕的事件 而在圖片之外則無事件反應。即可達到新手引導的要求