現在網上關于3.0的資料實在是有點少,不過我還是很喜歡3.0的風格的,C++11也帶來了很多友善。
其實說的是4種觸摸機制,其實有一部分cocos2dx已經不建議用了,會爆出大量警告。
第一種是采用函數回調,主要是用于MenuItem
// a selector callback
void menuCloseCallback(Object* pSender);
auto closeItem = MenuItemImage::create("CloseNormal.png","CloseSelected.png",
CC_CALLBACK_1(HelloWorld::menuCloseCallback, this));
void HelloWorld::menuCloseCallback(Object* pSender)
{
Director::getInstance()->end();
#if (CC_TARGET_PLATFORM == CC_PLATFORM_IOS)
exit(0);
#endif
}
從上面的代碼也可以看得到3.0的一些改變
用CC_CALLBACK_x代替了 按鈕的menu_selector(),update的 schedule_selector 回調接口,其中最後一個x代表着回調函數的參數有幾個,0表示0個,1表示1個,2表示2個,上面的例子是1個參數,是以用CC_CALLBACK_1
第二種方法我也不是很明白,TouchEvent響應
這是新加入的響應方式。它主要是使用在UIWidget上的。可以将其看做是函數回調的一個擴充,為更多的響應處理提供可能。使用方法大緻是:
//聲明
void touchButton(Object* object,TouchEventType type);
//挂接到控件上
uiButton->addTouchEventListener(this,toucheventselector(HelloWorld::touchButton));
//實作
void HelloWorld::touchButton(Object* object,TouchEventType type)
{
LabelTTF* label;
switch (type)
{
case TouchEventType::TOUCH_EVENT_BEGAN:
label = static_cast<LabelTTF*>(getChildByTag(11));
label->setString("按下按鈕");
break;
case TouchEventType::TOUCH_EVENT_MOVED:
label = static_cast<LabelTTF*>(getChildByTag(11));
label->setString("按下按鈕移動");
break;
case TouchEventType::TOUCH_EVENT_ENDED:
label = static_cast<LabelTTF*>(getChildByTag(11));
label->setString("放開按鈕");
break;
case TouchEventType::TOUCH_EVENT_CANCELED:
label = static_cast<LabelTTF*>(getChildByTag(11));
label->setString("取消點選");
break;
default:
break;
}
}
因為所有的UIWidget都要添加到UILayer上,而UILayer通常都會在最上層,是以可以“基本上”認為這種使用方式會優先于其他方式處理點選消息。因為UILayer也會有層級的改變,比如它和MenuItem之間的關系。是以說“基本上”。
第三種 觸摸監聽綁定
我覺得這種方法相當友善,不僅可以綁定在精靈上,還可以綁定在層上,觸摸函數也可以用lambda來寫。下面是方法
auto listener1 = EventListenerTouchOneByOne::create();//建立一個觸摸監聽
listener1->setSwallowTouches(true);//設定是否想下傳遞觸摸
Rect rect = Rect(qipanPoint.x,qipanPoint.y
,qipanSize.width,qipanSize.height);
//3.0 後可以直接在touchBegan後添加它的實作代碼,而不用特意去寫一個touchBegan的函數
listener1->onTouchBegan = [rect,this](Touch* touch, Event* event){ //[]中間的是傳入的參數
auto target = static_cast<Sprite*>(event->getCurrentTarget());//擷取的目前觸摸的目标
Point locationInNode = target->convertToNodeSpace(touch->getLocation());
Size s = target->getContentSize();
if (rect.containsPoint(locationInNode))//判斷觸摸點是否在目标的範圍内
{ //以下是我自定義的一些操作
//建立鎖定精靈
auto lockSprite = Sprite::create("lock.png");
lockSprite->setPosition(GetQiziPoint(locationInNode,rect));
lockSprite->setTag(99);
this->addChild(lockSprite);
return true;
}else
return false;
};
//拖動精靈移動
listener1->onTouchMoved = [rect,this](Touch* touch, Event* event){
auto target = static_cast<Sprite*>(event->getCurrentTarget());//擷取的目前觸摸的目标
Point locationInNode = target->convertToNodeSpace(touch->getLocation());
Size s = target->getContentSize();
if (rect.containsPoint(locationInNode))//判斷觸摸點是否在目标的範圍内
{
//鎖定精靈移動
Sprite *lockSprite = (Sprite*)this->getChildByTag(99);
lockSprite->setPosition(GetQiziPoint(locationInNode,rect));
}
};
listener1->onTouchEnded = [=](Touch* touch, Event* event){ // =在c++11裡面代表這個lambda表達式中能使用外面的變量
this->removeChildByTag(99);//移除鎖定精靈
};
//将觸摸監聽添加到eventDispacher中去
_eventDispatcher->addEventListenerWithSceneGraphPriority(listener1 ,layer);
這篇文章參考了下面兩篇文章;
Cocos2d-x 3.0開發(3)點選互動的四種處理
Cocos2dx 3.0 提高篇(二) 事件回調