中文字幕av专区_日韩电影在线播放_精品国产精品久久一区免费式_av在线免费观看网站

溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

cocos2dx基礎篇(9)——觸碰事件Touch

發布時間:2020-08-05 20:39:42 來源:網絡 閱讀:14093 作者:shahdza 欄目:開發技術

【嘮叨】

    cocos2dx游戲引擎的重點是在于移動設備的跨平臺開發,而移動設備上的游戲大部分都是通過屏幕觸碰來進行的。比如主菜單的按鈕觸碰,打飛機中飛機的觸碰移動,都需要用到觸碰操作。想一想之前講的菜單按鈕CCMenu,菜單項的點擊響應事件,其實就是觸碰。

    cocos2dx引擎中實現觸碰的類CCTouchDelegate。而CCLayer類默認繼承了CCTouchDelegate接口,所以CCLayer的子類無須再重新使用這些接口,這樣就很方便地為我們提供了觸摸操作相關的操作。

    觸碰事件主要分為兩類:單點觸碰多點觸碰

    本節組織結構如下:

        一、單點觸碰TargetedDelegate、以及參數CCTouch類。

        二、多點觸碰StandardDelegate、以及參數CCSet類。

        三、兩類觸碰的區別。


【Demo下載】

    https://github.com/shahdza/Cocos_LearningTest/tree/master/demo_%E8%A7%A6%E7%A2%B0%E4%BA%8B%E4%BB%B6Touch 


【3.x】

    請移步:http://shahdza.blog.51cto.com/2410787/1560222




【單點觸碰】

    單點觸碰TargetedDelegate,顧名思義,就是只接受一個點的觸摸響應事件。

    在使用觸碰之前,必須要先注冊觸碰委托。單點觸碰的注冊委托函數為addTargetedDelegate


1、開啟單點觸碰事件addTargetedDelegate

    寫在onEnter()中。

//
/**        
 *		開啟單點觸碰TargetedDelegate
 *		注冊觸碰:addTargetedDelegate("觸碰事件委托的對象","優先級","是否攔截觸屏事件");
 *		優先級的值越小,就越高越早被響應。
 *		當第3個參數為true時,表示對本次觸屏事件進行攔截,也就是說當觸屏事件響應了本次觸屏委托后,將不會再繼續響應其他觸碰委托。
 */
	void HelloWorld::onEnter() 
	{
		//注冊觸碰響應事件
		CCDirector::sharedDirector()->getTouchDispatcher()->addTargetedDelegate(this,0,false);
		CCLayer::onEnter();//一定不要忘了調用父類的onEnter
	}
//


2、關閉單點觸碰事件removeDelegate

    寫在onExit()中。

//
/**        
 *		關閉單點觸碰TargetedDelegate
 *		注銷觸碰:removeDelegate("注銷觸碰事件委托的對象");
 */
	void HelloWorld::onExit()
	{
		//注銷觸屏響應事件
		CCDirector::sharedDirector()->getTouchDispatcher()->removeDelegate(this);
		CCLayer::onExit();//一定不要忘了調用父類的onExit
	}
//


3、單點觸碰響應函數

    ccTouchBegan、ccTouchMoved、ccTouchEnded、ccTouchCancelled。

    其中ccTouchBegan的返回值為bool類型:

        當返回true時 ,表示繼續響應ccTouchMoved、ccTouchEnded事件;

        當返回false時,則不再繼續響應這兩個事件。

//
	virtual bool ccTouchBegan(CCTouch* touch,CCEvent* event);        //手指碰到屏幕時調用
	virtual void ccTouchMoved(CCTouch* touch,CCEvent* event);        //手指在屏幕上滑動時調用
	virtual void ccTouchEnded(CCTouch* touch,CCEvent* event);        //手指離開屏幕是調用
	virtual void ccTouchCancelled(CCTouch *pTouch, CCEvent *pEvent); //取消觸碰
//


4、關于CCTouch類

    CCTouch類是用來存儲用戶觸摸屏幕的過程中,其觸摸點的相關信息。也就是保存了觸碰的整個過程中,手指所在的位置坐標。

    需要在.h中添加引用命名空間:using namespace cocos2d; 才可以使用。

    常用操作如下:

//
	class CCTouch : public CCObject        
	{
		CCPoint getLocation();         //返回當前觸點的坐標
		CCPoint getPreviousLocation(); //返回前一個觸點的坐標
		CCPoint getStartLocation();    //返回開始觸碰時的坐標
		CCPoint getDelta();            //返回最近兩個觸點的偏移量坐標
	};
//


5、代碼實戰

    接下來將舉個例子:使用單點觸碰實現精靈的移動


    5.1、聲明單點觸碰響應函數

    先在HelloWorld.h中,聲明觸碰響應函數,以及類的生命周期。

//
	//觸屏事件
	virtual bool ccTouchBegan(CCTouch* touch,CCEvent* event);
	virtual void ccTouchMoved(CCTouch* touch,CCEvent* event);
	virtual void ccTouchEnded(CCTouch* touch,CCEvent* event);

	//生命周期
	virtual void onEnter();
	virtual void onExit();
//

    

    5.2、開啟、關閉單點觸碰事件

    在HelloWorld.cpp中編寫開啟和關閉觸碰事件。

//
	//開啟觸屏監聽
	void HelloWorld::onEnter() 
	{
		CCDirector::sharedDirector()->getTouchDispatcher()->addTargetedDelegate(this,0,false);
		CCLayer::onEnter(); //一定不要忘了
	}

	//關閉觸屏監聽
	void HelloWorld::onExit()
	{
		CCDirector::sharedDirector()->getTouchDispatcher()->removeDelegate(this);
		CCLayer::onExit();  //一定不要忘了
	}
//

    

    5.3、創建測試精靈

    在HelloWorld::init()中創建一個CCSprite精靈,用于測試觸碰。

//
	//添加一個CCSprite精靈
	CCSprite* sp = CCSprite::create("Icon.png");
	sp->setPosition( midPos );
	this->addChild(sp, 0, 1); //tag標記為1
//

    

    5.4、實現觸碰響應函數

    ccTouchBegan:將精靈的位置設置到觸碰開始的位置。關鍵函數:touch->getLocation()

    ccTouchMoved:對精靈的位置進行移動。            關鍵函數:touch->getDelta()

    ccTouchEnded:將精靈的位置還原到觸碰開始的位置。關鍵函數:touch->getStartLocation()

//
	//觸屏開始ccTouchBegan
	bool HelloWorld::ccTouchBegan(CCTouch* touch,CCEvent * event) 
	{
		CCLOG("ccTouchBegan");

		//獲取CCSprite精靈
		CCSprite* sp = (CCSprite*)this->getChildByTag(1);

		//設置精靈的坐標為: 當前觸點位置
		CCPoint pTouch = touch->getLocation();
		sp->setPosition( pTouch );

		return true;
	}

	//觸屏移動ccTouchMoved
	void HelloWorld::ccTouchMoved(CCTouch* touch,CCEvent* event) 
	{
		CCLOG("ccTouchMoved");

		//獲取可視區域尺寸大小
		CCSize mysize = CCDirector::sharedDirector()->getVisibleSize();

		//獲取CCSprite精靈
		CCSprite* sp = (CCSprite*)this->getChildByTag(1);

		//實現精靈的觸屏移動
		CCPoint pos = touch->getDelta();        //獲得觸屏滑動的偏移量
		CCPoint currentPos = sp->getPosition(); //獲得精靈的當前坐標

		currentPos = ccpAdd(currentPos, pos);   //精靈+偏移量 后的坐標

		sp->setPosition(currentPos);            //設置觸屏移動后的坐標
	}


	//觸屏結束ccTouchEnded
	void HelloWorld::ccTouchEnded(CCTouch* touch,CCEvent* event) 
	{
		CCLOG("ccTouchEnded");

		//獲取CCSprite精靈
		CCSprite* sp = (CCSprite*)this->getChildByTag(1);

		//設置精靈的坐標為: 觸屏開始時的觸點位置
		CCPoint touchStartPos = touch->getStartLocation();
		sp->setPosition( touchStartPos );
	}
//

    

6、運行結果

cocos2dx基礎篇(9)——觸碰事件Touch




【多點觸碰】

    多點觸碰StandardDelegate,可以支持多個點的同時觸摸響應事件。


1、開啟多點觸碰

    多點觸碰的委托注冊放在onEnter的生命函數中會造成程序異常退出。

    所以注冊多點觸碰都需要重寫如下函數:registerWithTouchDispatcher

    開啟多點觸碰,除了注冊觸碰委托外,還需要調用setTouchEnabled(true)來啟用觸碰。

//
/**
 *		注冊多點觸碰,重寫registerWithTouchDispatcher。
 *		addStandardDelegate("觸碰事件委托的對象","優先級")
 */
	void HelloWorld::registerWithTouchDispatcher()
	{
		CCDirector::sharedDirector()->getTouchDispatcher()->addStandardDelegate(this,0);
	}


	//在HelloWorld::init()中啟用多點觸碰
	this->setTouchEnabled(true);
//


2、關閉多點觸碰

    與單點觸碰的關閉類似,寫在onExit()。

//
	void HelloWorld::onExit()
	{
		//關閉觸碰
		CCDirector::sharedDirector()->getTouchDispatcher()->removeDelegate(this);
		CCLayer::onExit(); //一定不要忘了
	}
//


3、多點觸碰響應函數

    ccTouchesBegan、ccTouchesMoved、ccTouchesEnded、ccTouchesCancelled。

    其中ccTouchesBegan和單點觸碰不同,返回值為void。

//
	virtual void ccTouchesBegan(CCSet* touches, CCEvent* event);       //觸碰開始
	virtual void ccTouchesMoved(CCSet* touches, CCEvent* event);       //觸碰移動
	virtual void ccTouchesEnded(CCSet* touches, CCEvent* event);       //觸碰結束
	virtual void ccTouchesCancelled(CCSet *pTouches, CCEvent *pEvent); //取消多點觸屏
//


4、關于CCSet類

    CCSet類是一個集合類,和C++中的Set是類似的。

    在這里CCSet的數據元素類型為CCTouch,其主要存儲的是多點觸碰的觸摸點CCTouch集合。

    使用迭代器CCSetIterator進行CCSet集合中多個觸點CCTouch的遍歷。

//
	for (CCSetIterator iter = touches->begin() ;iter != touches->end(); iter++) 
	{
		//獲取觸點后,就和單點一樣的處理了
		CCTouch* touch = (CCTouch*)(*iter);
		//......
	}
//


5、代碼實戰

    在電腦中無法看到多點觸碰的效果,因為……電腦操作只有一個鼠標cocos2dx基礎篇(9)——觸碰事件Touch

    下面就講解一個多點觸碰的例子吧,至于效果,自己將代碼移植到手機上看吧。。。


    5.1、聲明多點觸碰響應函數

    先在HelloWorld.h中,聲明多點觸碰響應函數,以及類的生命周期。

//
	//觸屏事件
	virtual void registerWithTouchDispatcher(void);
	virtual void ccTouchesBegan(CCSet* touches,CCEvent* event);
	virtual void ccTouchesMoved(CCSet* touches,CCEvent* event);
	virtual void ccTouchesEnded(CCSet* touches,CCEvent* event);

	//生命周期
	virtual void onExit();
//

    

    5.2、開啟、關閉多點觸碰事件

    在HelloWorld.cpp中編寫開啟和關閉多點觸碰事件。

//
	//在init中開啟多點觸碰
	bool HelloWorld::init()
	{
		//.....
		//開啟多點觸屏。注意這句話必須要寫,否則無法多點觸屏
		this->setTouchEnabled(true);
		//.....
	}

	//注冊多點觸屏
	void HelloWorld::registerWithTouchDispatcher()
	{
		CCDirector::sharedDirector()->getTouchDispatcher()->addStandardDelegate(this,0);
	}

	//注銷多點觸屏
	void HelloWorld::onExit()
	{
		CCDirector::sharedDirector()->getTouchDispatcher()->removeDelegate(this);
		CCLayer::onExit();  //不要忘了寫!
	}
//


    5.3、創建測試精靈

    在HelloWorld::init()中創建兩個CCSprite精靈,用于測試觸碰。

//
	//添加兩個CCSprite精靈,用于多點觸屏
	CCSprite* sp1 = CCSprite::create("Icon.png");
	sp1->setPosition( ccp( 100, 160 ) );
	this->addChild(sp1, 0, 1);

	CCSprite* sp2 = CCSprite::create("Icon_gray.png");
	sp2->setPosition( ccp( 200, 160) );
	this->addChild(sp2, 0, 2);
//


    5.4、實現多點觸碰響應函數

    ccTouchesMoved中:將精靈的位置設置到觸點位置,sp1精靈設置到第0個觸點位置;sp2精靈設置到第1個觸點位置。

    關鍵函數:

    (1)CCTouch* touch = (CCTouch*)(*iter)

    (2)touch->getID()

//
	//觸屏開始,返回值是void
	void HelloWorld::ccTouchesBegan(CCSet* touches,CCEvent* event)
	{
		CCLOG("ccTouchesBegan");
	}

	//觸屏移動
	void HelloWorld::ccTouchesMoved(CCSet* touches,CCEvent* event)
	{
		CCLOG("ccTouchesMoved");

		//創建CCSet的迭代器CCSetIterator
		CCSetIterator iter = touches->begin();

		//遍歷多點觸點集合touches
		for( ;iter != touches->end(); iter++) 
		{
			//獲取觸點后,就和單點一樣的處理了
			CCTouch* touch = (CCTouch*)(*iter);

			if( touch->getID() == 0)      //控制精靈sp1
			{
				CCSprite* sp1 = (CCSprite*)this->getChildByTag(1);
				sp1->setPosition( touch->getLocation() );
			}
			else if( touch->getID() == 1) //控制精靈sp2
			{
				CCSprite* sp2 = (CCSprite*)this->getChildByTag(2);
				sp2->setPosition( touch->getLocation() );
			}
		}
	}

	//觸屏結束
	void HelloWorld::ccTouchesEnded(CCSet* touches,CCEvent* event)
	{
		CCLOG("ccTouchesEnded");
	}
//

    

6、運行結果

cocos2dx基礎篇(9)——觸碰事件Touch


7、分析與總結

    灰的那張精靈sp2為啥不動啊啊啊!因為電腦中只有一個鼠標……所以只能觸碰一個點。cocos2dx基礎篇(9)——觸碰事件Touch

    想要看到多點觸碰的效果,就把程序移植到手機上吧。




兩類觸碰的區別】

    (1)單點使用的監聽類是CCtargetedTouchDelegate,而多點使用CCtangardTouchDelegate。

    (2)多點觸控還需要多一個步驟,就是單獨寫個函數來注冊多點觸控:registerWithTouchDispatcher。

    (3)多點觸控要有開啟才能用。 this->setTouchEnabled(true)。

    (4)多點觸控中的ccTouchesBegan不是布爾型。



向AI問一下細節

免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

AI

德兴市| 噶尔县| 临泉县| 无极县| 奉贤区| 宾阳县| 外汇| 图木舒克市| 谢通门县| 精河县| 民权县| 福清市| 邯郸市| 阿荣旗| 嘉黎县| 遂平县| 蒙自县| 崇明县| 新乡县| 南充市| 固安县| 龙海市| 内江市| 花莲县| 汾西县| 安新县| 中西区| 根河市| 开原市| 昔阳县| 安平县| 临夏市| 白玉县| 年辖:市辖区| 乌拉特中旗| 阜阳市| 乌兰浩特市| 伊金霍洛旗| 于都县| 含山县| 宁南县|