Cocos2d-x學習筆記(十六)-------->Cocos2d-x引擎中的網格地圖,cocos2d-x學習筆記
網格地圖
2D遊戲網格地圖介紹:在網格地圖遊戲中,地圖由稱為“瓷磚”(tile)的一小組圖片相互排列組成。這些圖片放在一個整體的網格中。得到一個令人信服的遊戲情境。網格地圖技術為開發人員提供了很多便利,使用很少的網格圖片元素,就可以組成非常大的情境地圖,而且這些大情境並不會浪費硬體資源。而且根據網格元素的不同,可以得到多種多樣的情境地圖。網格地圖主要分為兩大類:第一類是90度網格地圖(Orthogonal Tilemap),這類地圖都是使用正方形或者長方形的瓷磚(Tile)組成的,通常以俯視視角從上到下展示遊戲世界。
第二類是斜45度網格地圖(isometric),這類地圖採用棱形的瓷磚,使得顯示的內容達到了一種透視的效果,並且可以在遊戲中引入上下左右,左上、左下、右上、右下共8個方向,是一種近似於3D效果的網格地圖。
對於這兩種主流的網格地圖類型,x引擎都可以完美地支援。Cocos2d-x引擎支援標準的TMX格式的網格地圖檔案,這是一種使用網格地圖編輯器製作的檔案,讀取TMX格式檔案後,x引擎就能夠在情境中顯示出整個網格地圖,並對網格地圖中的層次資訊和各種地圖屬性進行操作,此時的網格地圖,就是x引擎情境中的一個“特大號”的節點。
使用網格地圖編輯器(Tiled Map Editor):Tiled Map Editor可以輕鬆地編輯出各種90度網格地圖和45度網格地圖,並將編輯好的內容儲存為TMX格式的檔案,由Cocos2d-x引擎讀取解析,顯示在遊戲情境當中。Tiled所編輯的網格地圖支援多個層,可以在地圖中添加觸發地區和物體,還可以為每個瓷磚添加類型屬性,然後使用Cocos2d-x在程式中用代碼訪問瓷磚的屬性值。
利用Tiled建立45度地圖:
利用Tiled建立90度地圖:
在Cocos2d-x引擎中使用網格地圖:
CCTMXTiledMap* map = CCTMXTiledMap::create("iso-test1.tmx");addChild(map, 0);
這部分代碼將網格檔案載入,在x引擎中網格地圖對應CCTMXTiledMap類型,通過這一類型的對象可以對網格地圖進行各種操作。接下來的代碼將網格地圖對象作為情境的一個子節點添加到遊戲情境當中。
效果:
將地圖置中顯示,為地圖對象設定錨點。
CCTMXTiledMap* map = CCTMXTiledMap::create("iso-test1.tmx");map->setAnchorPoint(ccp(0.5f,0.5f));map->setPosition(ccp(visibleSize.width/2, visibleSize.height/2));addChild(map, 0);
效果:
網格地圖的層次控制:在
Cocos2d-x引擎中,可以通過
CCTMXLayer類型來對網格地圖中的
layer對象進行各種操作,包括顯示
隱藏、
縮放等操作。在操作具體的
layer對象之前,需要通過
CCTMXTiledMap類型的
map對象得到
layer對象,然後才能夠對
layer對象進行控制操作。
CCTMXTiledMap* map = CCTMXTiledMap::create("iso-test1.tmx");map->setPosition(ccp(visibleSize.width/2, visibleSize.height/2));map->setAnchorPoint(ccp(0.5f, 0.5f));CCTMXLayer* layer1 = map->layerNamed("layer1");CCTMXLayer* layer2 = map->layerNamed("layer2");CCTMXLayer* layer3 = map->layerNamed("layer3");layer2->setVisible(false);addChild(map, 0);
首先是要
CCTMXTiledMap類型對象的
layerName方法以及每個層的名稱作為參數,取得
CCTMXLayer類型的
layer對象,然後我們就可以使用
layer對象進行
隱藏、
縮小及
放大操作了。
除了對
layer整體進行控制以外,還可以進一步取得
layer中某一個具體的網格單元,得到的是一個獨立的精靈對象,拿到對象後,就可以對它進行各種精靈操作,比如變換顏色等等,這樣就可以最終控制網格地圖的每個網格單元。
CCSprite* sprite;sprite = layer3->tileAt(ccp(8,7));sprite->setColor(ccc3(200,0,0));
還可以即時修改某個層次
layer指定單元格的內容。
layer3->setTileGID(32, ccp(8,7));
以上代碼修改了
layer3層次中座標為
(12,12)的這個單元格的映像
ID,當新的
ID指定為
32時,其對應的映像就是圖源中索引為
32的圖片單元。
效果:
網格地圖的移動控制:網格地圖對象在
Cocos2d-x引擎中,實質上就是情境內的一個特殊類型的節點。所以針對節點的所有操作,都可以放在網格地圖對象上進行。網格地圖往往都比較大,顯示的內容非常多,全部地圖的整體尺寸通常是遊戲螢幕的幾倍甚至是幾十倍,如果想要在遊戲中便遍曆整個地圖,就必須要對地圖做移動控制操作,讓遊戲螢幕的主網路攝影機(也就是當前螢幕視窗)從地圖的一點移動到另一點,其實質操作就是網路攝影機位置固定,讓網格地圖在情境中從一個點移向另一個點,這種反向操作也可以得到相同的效果。
以下代碼實現對地圖的觸摸移動操作:在
HelloWorldScene.h標頭檔加入:
virtual void ccTouchesMoved(CCSet *pTouches, CCEvent *pEvent);
然後在
HelloWorldScene.cpp中加入:
void HelloWorld::ccTouchesMoved(CCSet *pTouches, CCEvent *pEvent){CCTouch* touch = (CCTouch *)pTouches->anyObject();CCPoint diff = touch->getDelta();CCNode* node = getChildByTag(1);CCPoint currentPos = node->getPosition();node->setPosition(ccpAdd(currentPos, diff));}
這個函數中首先得到了使用者的觸摸點,在
x引擎中使用
CCTouch類型代表觸摸點資訊,接下來使用觸摸點對象
touch的
getDelta方法,得到當前觸摸點在兩幀間隔時間內在
X軸和
Y軸方向上的移動距離。得到每次手指滑動的距離後,根據這個位置變化,更新地圖的位置座標。使用
getChildByTag(1)這個方法得到網格地圖節點,之所以能夠通過這個方法取得網格地圖對象,是因為在向情境中添加網格地圖時,使用
addChild(map,0,1),第三個參數指定了這個網格地圖的
tag標籤為
1。再通過標籤就能夠找回網格地圖對象,此時它的類型就是一個情境節點,可以通過
getPosition()取得此節點的座標位置,通過
setPosition()可以設定它的新位置座標。
效果:
網格地圖的遮擋操作:在設計採用大地圖的遊戲時,除了地圖上的元素內容以外,我們通常還要加入遊戲
主角、
NPC等人物角色。人物在地圖行走時,需要注意的一點就是與地圖中的物體的遮擋效果。比如:人物在沙漠中行走,人物是在地表的上層,而當任務走入森林時,數目就應該位於人物的上層,表示人物被樹木遮擋住了。首先設定網格地圖中每個層次的顯示順序——
ZOrder,通過以下代碼設定第一層和第二層的顯示層級比較低,會被主角精靈遮擋住,而第三層森林層顯示層級要高很多,不會被主角精靈遮擋。
layer1->setZOrder(1);layer2->setZOrder(2);layer3->setZOrder(10);
參數1、2、10就是每個層的顯示層級,數值越大,層級越高,進階別的會遮擋住低層級的物體。
CCSprite* sprite = CCSprite::create("iso-test.png", CCRectMake(274,0,48,114));sprite->setPosition(ccp(350, 300));sprite->setAnchorPoint(ccp(0.5f,0.5f));map->addChild(sprite, 3);CCActionInterval* move = CCMoveBy::create(3, ccp(200, -200));CCActionInterval* back = move->reverse();CCActionInterval* seq = CCSequence::create(move, back, NULL);sprite->runAction(CCRepeatForever::create(seq));
效果: