天天看點

COCOS2DX3.0的3種觸摸響應機制第一種是采用函數回調,主要是用于MenuItem第二種方法我也不是很明白,TouchEvent響應第三種 觸摸監聽綁定

現在網上關于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 提高篇(二) 事件回調

繼續閱讀