[cocos2d-x]TiledMap地圖的學習-雙指縮放,單指拖動,雙擊自動放大

根據http://www.raywenderlich.com/1163/how-to-make-a-tile-based-game-with-cocos2d 中的介紹來在cocos2d-x上實現。


文章內容:

一、Tiled工具的使用

二、Touch事件的檢測,拖動和縮放操作


一、實現Tiled免費地圖工具編輯

1、安裝工具,從Tiled Map Editor下載並且安裝,然後打開

按左上角那個new一個新地圖:


地圖大小:塊的數量,並不是像素

塊大小:就是1個方塊的大小,地圖由N個方塊組成


然後創建地圖資源,點擊工具欄:地圖-新圖塊



名稱自定義,當然符合一般命名標準,- -切忌中文。

圖像-瀏覽-選擇下載的素材


其他定義根據剛剛新建地圖的設置來,注意邊距跟製作的圖像有關係,上圖我們看到每個小塊都有1個1像素的透明黑邊,其實這個就是爲了塊圖之間能保證其正常像素不偏差,和unity3d中生成atlas是一個道理的,也可以設置padding調整,扯遠了。哈哈

大家摸索下這些按鈕就應該懂什麼意思了。我製作好的圖。

我設置了我的layer爲Background





2、把TMX文件提供給cocos2d-x項目並且使用上去


右鍵-add files這步就不說了。

代碼部分:

在HelloWorld的layer頭文件增加2個關於tmx對象的定義,一個地圖,一個地圖層



Helloworld實現文件的操作



然後大膽地點擊編譯吧!


驚恐一啓動就暫停了。

淡定,一看就知道是創建tmx map時候報錯了。

我們觀察下導入的TMX文件內容:


選中的部分就是需要改的,這裏注意了:

因爲我的地圖文件png是放到下載下面的,然而編譯時候,是不會存在../Downloads……這個目錄。

我們改成直接就是Resource根目錄:



再運行:



很帥是麼? 這裏我們注意看,地圖顯示的就是左下角,也就是製作的地圖的(0,0)點在左下角對着屏幕左下角。下面將嘗試地圖的移動以及縮放等操作!




二、Touch事件的檢測

virtual void registerWithTouchDispatcher();
virtual bool ccTouchBegan(CCTouch *pTouch, CCEvent *pEvent); //這個方法必須實現
virtual void ccTouchEnded(CCTouch *pTouch, CCEvent *pEvent);


首先在Helloworld的頭文件中虛繼承關於CCTouchDispatcher、
TouchDelegate的一些事件。下面我們認識下這3個方法:

關於virtual void registerWithTouchDispatcher(); 首先這個用來幹嘛的呢?

/** @brief CCTouchDispatcher.
 Singleton that handles all the touch events.
 The dispatcher dispatches events to the registered TouchHandlers.
 There are 2 different type of touch handlers:
   - Standard Touch Handlers
   - Targeted Touch Handlers
 
 The Standard Touch Handlers work like the CocoaTouch touch handler: a set of touches is passed to the delegate.
 On the other hand, the Targeted Touch Handlers only receive 1 touch at the time, and they can "swallow" touches (avoid the propagation of the event).
 
 Firstly, the dispatcher sends the received touches to the targeted touches.
 These touches can be swallowed by the Targeted Touch Handlers. If there are still remaining touches, then the remaining touches will be sent
 to the Standard Touch Handlers.

 @since v0.8.0
 */

上面是官方定義的CCTouchDispatcher的描述,我們知道有2種實現和處理觸碰的消息,標準觸碰、目標觸碰。

http://cn.cocos2d-x.org/document/index/class?url=da/de4/classcocos2d_1_1_c_c_touch_dispatcher.html 這是官方中文翻譯的一個解釋。

標準觸碰是統一處理所有的消息,而目標觸碰就是單一的處理,並且能過濾其他消息。所以一般我們準確性觸碰的處理建議還是使用目標觸碰模式。

怎麼啓動Targeted Touch Handlers??


如果瞭解監聽者模式的應該瞬間能理解,默認在初始化時候

1、設置

this->setTouchEnabled(true);

2、繼承和實現

定義

virtual void registerWithTouchDispatcher();
實現如下:
void HelloWorld::registerWithTouchDispatcher(){
    CCDirector::sharedDirector()->getTouchDispatcher()->addTargetedDelegate(this, 0, true);
}

這裏說一下,正常的監聽者模式需要:使用前註冊,使用後移除!當我們繼承和實現了

registerWithTouchDispatcher

那麼移除的操作會自動在OnExit時候執行,不需要我們去關心!


3、使用想要監聽的觸碰消息方法,注意一個觸碰一定會有“開始”,所以

virtual bool ccTouchBegan(CCTouch *pTouch, CCEvent *pEvent); //這個方法必須實現

其他方法可以從CCTouchDispatcher定義裏面查找。


三、iOS多點觸碰的使用,實現雙指縮放,單指拖動,雙擊自動縮放和移到目標位置!

注意:以下先說明怎麼啓動“標準觸碰”方式,但這個方式我不建議,因爲~~~後面會看到原因!

1、啓動iOS端多點觸碰,默認是關閉的

//open iOS multiple touch.
    [__glView setMultipleTouchEnabled:YES];

把以上添加到ios目錄中的AppController.mm程序啓動回調裏面。也就是默認iOS啓動處理文件。

2、Layer檢測觸碰信息方法

2.1、需要啓動

layer初始化時候啓動觸碰支持: this->setTouchEnabled(true);

2.2、繼承實現觸碰的方法

// optional
     virtual void ccTouchesBegan(CCSet *pTouches, CCEvent *pEvent) {CC_UNUSED_PARAM(pTouches); CC_UNUSED_PARAM(pEvent);}
     virtual void ccTouchesMoved(CCSet *pTouches, CCEvent *pEvent) {CC_UNUSED_PARAM(pTouches); CC_UNUSED_PARAM(pEvent);}
     virtual void ccTouchesEnded(CCSet *pTouches, CCEvent *pEvent) {CC_UNUSED_PARAM(pTouches); CC_UNUSED_PARAM(pEvent);}
     virtual void ccTouchesCancelled(CCSet *pTouches, CCEvent *pEvent) {CC_UNUSED_PARAM(pTouches); CC_UNUSED_PARAM(pEvent);}

以上方法就是在CCTouchDelegateProtocol裏面,注意觀察和上述第一點說的目標觸碰不一樣就是,這裏處理的是所有信息,從傳參可看,pTouches代表了多點的意思。

通常大家從cocos2d-iPhone的例子中可以用

    UITouch* touch1 = [[[event allTouches] allObjects] objectAtIndex:0];
    UITouch* touch2 = [[[event allTouches] allObjects] objectAtIndex:1];
沒錯,感覺CCSet是不是和NSSet很像呢?但我很肯定告訴你,這裏是不一樣的,CCSet並不擁有objectAtIndex這個方法,當然你也可以用它的迭代器去取每一個觸碰點。

但我實踐可以告訴你,結果並不如意。即使你固定這個CCTouch* touch1->GetID() == 0 來判斷,用“標準觸碰”來檢測雙指縮放,依舊會出現參雜的情況!參雜也就是明明2隻手指,但卻突然會檢測到是1隻手指的時候!!kiding me?抓狂

經過參看CCScrollView中,我發現,原來註冊使用“目標觸碰”來處理多點觸碰其實非常好!因爲我前面說了,每一個觸碰點都會單獨經歷Begin->Moved->End;所以我們可以新建一個CCArray來記錄進入Begin的觸碰CCTouch點!

bool SimpleDragZoomLayer::ccTouchBegan(cocos2d::CCTouch *pTouch, cocos2d::CCEvent *pEvent){
    if (m_pTouches->containsObject(pTouch) == false) {
        m_pTouches->addObject(pTouch);
    } ……

然後分別通過m_pTouches的數量來檢測是單指操作,還是雙指操作!

下面是我的一個實現邏輯,當然你有更好的解決,或者針對我的實現可以幫忙提高下代碼的控制用戶體驗非常歡迎提供反饋~


具體內容請看實現的例子項目,使用的話,可以直接用

    //create zoom and drag controller for this layer.
    SimpleDragZoomLayer::create(_tiledMap);

把它賦給需要控制的layer即可,當然一般是地圖層!

項目源代碼:分數有點多~實在抱歉了。尊重版權~謝謝~微笑

http://download.csdn.net/detail/chiuan/5060318



發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章