近段時間主要是在研究開發工具與遊戲製作的結合,大家知道工慾善其事必先利其器,一款好的方便的開發工具能夠極大的提高遊戲的開發效率,特別是在製作關卡這些東西的時候,這也就是爲什麼國外現在有這麼多的開發引擎工具,特別是3d的比如unity3d,unreal,cryEngine等等都是基於這種需求而開發的。
那麼我這個新系列的博客也就是教大家如何使用TileMap這款地圖編輯器來提高大家在製作2d地圖方面的效率。
這邊我可能主要介紹的是一些高級用法,2d地圖編輯器的一些基礎用法如果大家還不清楚的就自己去百度一下,查查資料了。
下面進入正題,首先提供一下TileMap的下載地址
http://www.mapeditor.org/
TileMap是一款開源的地圖編輯器,使用qt開發,因此可以跨平臺,而且因爲開源,所以大家還可以根據自己的需求進行加工和修改,這一點是很重要。
這裏爲剛接觸遊戲開發的同學插一句,爲什麼要開發地圖編輯器呢,我們就用整張圖做地圖不就好了嗎?
這裏簡單回答一下,好處有兩個:www.it165.net
第一個是極大的減少用圖的面積,這樣就減少了在運行時系統佔用的內存,具體原理問你們的boss或者度娘。
第二個好處是可以通個打散的地圖方便在格子中做很多事件,方便判斷,比如做地圖行走障礙判斷,做觸發事件判斷。
下載之後安裝,打開編輯器如下。
點擊新建地圖,彈出如下方框
編輯器地圖方向可以選擇 “正常”或者“45度”兩種,這個是很多其他編輯器沒有的功能,大部分的編輯器都只支持單一方向的地圖編輯,所以這也是我選擇TileMap這款編輯器來開發的原因。
地圖大小表示地圖格子數的多少,30*30 的話就是一共900個格子
右邊的塊大小表示單個格子的大小,這裏是64*32, 一般正方向地圖塊大小都是一致的,這邊我們使用32*32。
按確定之後如下圖
下面我們添加圖片資源
點擊“地圖”->新圖塊,彈出下框
點擊“瀏覽”按鈕選擇一張圖片,這裏我們用cocos2d-x裏面自帶的很有代表性的圖片,路徑如下
cocos2d-2.0-x-2.0.2\samples\TestCpp\Resources\TileMaps\tmw_desert_spacing.png
這裏塊的寬高就是32,說一下邊距和間距的意思,
邊距就是指兩個塊之間橫向的間隔
間距就是指兩個塊之間縱向的間隔
我們看到圖片上有很多黑色線,一般大家之前做的圖塊是不會加這些間隔線的,但是可能有特殊情況,那現在我們就遇到了,所以現在如果我們這邊不加間距和邊距的話,切出來的圖塊就會出現問題。
大家可以看見這裏是我沒有設置間距和邊距切出來的圖塊,明顯的偏差的像素會越來越多,
下面我們把這張圖塊先刪除,再重新添加原圖塊
點擊圖塊下方的“垃圾桶”按鈕刪除圖塊。
下面我們看看設置邊距間距之後,這裏我們都設置爲1個像素
好了,我們看見圖塊的分割白線已經把圖片上本身的黑色線完美覆蓋,說明我們的設置是正確的,下面就可以用圖塊來拼接一張地圖了
這一排就是工具按鈕,一般做地圖的時候用前3個按鈕
第一個是圖章,單個刷,或者一個矩形的圖塊刷用這個工具
第二個是填充,
第三個是橡皮擦
大家試一下就知道用法了,記住,在圖塊層上的時候可以用鼠標一次框選一個矩形的圖塊哦,然後用第一個圖章刷就很方便快速了。
好了,大家都練習一下吧。
最後導出就點擊 文件->另存爲就行了。
這裏再教大家幾個小技巧:
選中圖塊,按鍵盤“X”快捷鍵可以實現圖塊原地水平翻轉,“Y”是垂直翻轉,
“Z”鍵可以循環90度翻轉。非常實用。
還有一個隨機模式的按鈕
這個按鈕的作用是當選中之後
然後在地圖塊上框選一大塊地圖,這時候在地圖上繪製的時候會隨機從你選中的很多圖塊中裏面選取一個繪製在地圖上效果如下
另外,所有TileMap中的指令大家可以在這裏查到
https://github.com/bjorn/tiled/wiki/Keyboard-Shortcuts
現在應該知道學好英語的重要性了吧
cocos2d-x中講解TileMap地圖編輯器的高級用法(一)
上一篇教大家做好了一張地圖,那麼我們如何在真正的遊戲中使用呢,這一篇就是主要教大家在cocos2d-x中使用
我們把上一篇做好的地圖保存後,放置在遊戲項目的資源目錄下
那麼我們包含地圖的代碼其實非常簡單
1.
CCTMXTiledMap*
map = CCTMXTiledMap::create(
"myTest.tmx"
);
2.
addChild(map);
就用這兩句話就把我們的地圖tmx文件加入到layer,addchild之後,這張地圖就會繪製出來了
下面講點新的東西
第一:圖塊設置技巧及注意事項
點擊 圖層 ->添加圖層
層上的名字我們改成英文,大家記住做程序的時候所有東西都改成英文,不管是文件名,標籤名,包括文件存放路徑都不要包括中文,反正除了我們遊戲裏面需要的界面或者對話,或者類似必須要用中文的東西,其他都一定用英文來表示。畢竟計算機是老外發明的,我們就按人家的規則來玩吧。
修改後
這樣表示層1,層2
這樣加多層之後就可以做一些遮罩效果了。
現在說一下多層會遇到的一些問題
每個層都可以用很多不用的圖片,但是有一個規則一定要記住
你在同一層使用的圖片塊大小一定要一致,比如你之前用32*32的圖片塊拼了一部分,那麼後面你換了另一個圖片的塊大小也必須是32*32的,不能是其他大小,如果你用了兩種大小,編輯器裏面不會出問題,但是一旦你使用在cocos2d-x中
CCTMXLayer類會報以下錯誤 www.it165.net
CCAssert( m_uMaxGID >= m_pTileSet->m_uFirstGid &&
m_uMinGID >= m_pTileSet->m_uFirstGid, "TMX: Only 1 tilset per layer is supported");
看清楚了嗎,TMX: Only 1 tilset per layer is supported
“每層只支持一種圖塊尺寸設置”
所以大家這個地方要注意
這裏再講下第二個地圖塊切塊要注意的地方
如果有以前用過地圖編輯器的同學肯定清楚,一般的地圖編輯器設定了地圖的塊大小的話,那麼圖片的塊切割大小也就必須是和地圖單塊的大小一致的
但是我們的TileMap這款編輯器可以分開設置
例如地圖塊大小設置32*32,圖片塊大小我可以設置成52*64,或者其他64*31
都可以,等你設置好了,在地圖塊填充的時候就會發現,TileMap會自動以左下角爲
對齊點。比如我把一個圖片切成60*64的圖片效果如下
看見了嗎,深色部分表示我放置的點,那麼超過的部分就自動向上和向右延伸了,
所以我們會看見在cocos2d-x的TileMaps資源下面會有這樣的圖存在
ok,圖片設置基本就講這麼多,下一篇教大家加入對象層和設置tile塊的一些屬性,可以在遊戲中做的一些事情。
cocos2d-x中講解TileMap地圖編輯器的高級用法(二)
上一篇教大家了一些TileMap地圖塊設置的基本規則和注意事項
這一篇開始教大家些複雜的東西:
如何通過地圖塊的id做一些事件的判斷。
這裏先解釋下圖塊的id是什麼:
圖塊的id就是當你加載地圖圖片的時候通過設置圖片切塊的大小會把一張地圖圖片切成很多小塊,這些小塊會自動編成一個一維數組,從0開始,如下所示
第一步:首先解決第一個問題:如何獲取圖塊id
因爲圖塊首先是畫在圖層上的,所以我們先得找到對應的圖層
1.
map
= CCTMXTiledMap::create(
"maps/Test2.tmx"
);
2.
CCTMXLayer*
walklay = map->layerNamed(
"layer0"
);
ok,現在walklay就是我們要判斷地圖id的圖層了,通過layer0這個圖層名字獲得了。
跟編輯器裏面的標籤要對應上
好了現在得到層了,就得找對應id了。
第二步:
也很簡單,如果我們想獲取圖層5行6列的地圖塊id是多少,www.it165.net
1.
CCPoint
pp = ccp(
6
,
5
);
//這裏第一個參數是列數,第二個是行數,特別注意
2.
unsigned
int
id
= layer0->tileGIDAt(pp);
ok,現在id 就是我們得到的圖塊的索引值了。
想獲得其他圖層的其他格子上的圖塊索引值同理。
得到這個值能幹什麼呢??
舉例:
1、做人物行走阻擋,比如我判斷如果地圖上所有索引爲5的圖塊不能行走。
2、更換圖塊,比如我設置所有格子id爲5的格子不顯示。
。。。。
等等,根據不同的遊戲我們可以有很多種的用途。
之前三篇地圖主要講的都是地圖繪製有關的部分,這一篇就講一講如果添加對象層,以及如何處理對象層的信息
我們點擊 圖層->添加對象層
這裏就會出現一個新的對象層,區別於圖層,用紫色標記
同樣的,我們更改下名字,變爲“object0”
光加了層沒用,我們還得在層上標記具體的對象
下面我們把光標點中“object0”對象層
我們可以看見工具欄有了變化
前面與圖層有關的按鈕變爲了灰色,後面與對象層有關的按鈕變亮了
點擊 “插入對象”
按鈕
然後我們用鼠標在地圖上拖出一個框來,格子數多少可以自由決定
,不過一般我們就使用一格就好了,
按住右下角的小正方形可以拖拉改變格子的大小
下面我們給對象添加屬性
右鍵點擊對象,彈出下框
點擊對象屬性
這裏上面第一排的名稱是方便在編輯器查看用的,因此最上面的“名稱”和類型處不填也可以。
下面我們加一個新的屬性,命名爲playerBorn吧,表示遊戲人物主角的出生地
值可以指定爲1,下面再定義個Hp的屬性,值寫個100,表示主角出生血量爲100
確定保存,之後加入到我們的遊戲工程目錄下 www.it165.net
第二步:讀取屬性信息
01.
CCTMXObjectGroup*
group = map->objectGroupName(
"object0"
);
//第一步,獲取對象層
02.
CCArray*
objects = group->getObjects();
//獲取層上對象集合
03.
CCDictionary*
dict = NULL;
04.
CCObject*
pObj = NULL;
05.
CCARRAY_FOREACH(objects,
pObj)
//遍歷對象集合中的對象
06.
{
07.
dict
= (CCDictionary*)pObj;
//
08.
if
(!dict)
09.
break
;
10.
const
char
*
key =
"playerBorn"
;
//設定關鍵字,對應我們的"playerBorn"
11.
CCString
*str = (CCString*)dict->objectForKey(key);
12.
if
(str)
13.
{
14.
key
=
"x"
;
15.
float
x
= ((CCString*)dict->objectForKey(key))->floatValue();
//獲取對應對象的x座標
16.
key
=
"y"
;
17.
float
y
= ((CCString*)dict->objectForKey(key))->floatValue();
//獲取對應對象的y座標
18.
player->setPosition(ccp(x,y));
//這裏player是我們的主角sprite對象,設置座標位置
19.
key
=
"hp"
;
20.
int
Hp
= ((CCString*)dict->objectForKey(key))->intValue();
//獲得主角血量100
21.
player->setHp(Hp);
22.
break
;
//找到過後,退出循環
23.
}
24.
}
這裏有個地方大家要注意,在編輯器上,我們的x,y屬性中的值是格子數,
比如
這裏,x是15,y是16,表示的是這個對象在地圖的16行15列的格子上,
但是在cocos2d-x中用讀取出來的就不是15,16了,而是自動乘過塊大小後在地圖上的像素值了,所以這就是爲什麼我設置主角setPosition的時候,直接用的轉換後的,xy值,而沒有再用他們去乘以tile塊的寬高的原因
基本使用就是這樣了,下一篇教大家如何處理斜45度角的地圖。