免責申明(必讀!):本博客提供的全部教程的翻譯原稿均來自於互聯網,僅供學習交流之用,切勿進行商業傳播。同時,轉載時不要移除本申明。如產生任何糾紛,均與本博客全部人、發表該翻譯稿之人無任何關係。謝謝合做! css
原文連接地址:http://www.raywenderlich.com/1163/how-to-make-a-tile-based-game-with-cocos2d html
教程截圖: java
在這個2部分的教程中,我將會教你們如何使用cocos2d來作一個基於tile地圖的遊戲,固然還有Tiled地圖編輯器。(咱們小時候玩的小霸王小學機裏面的遊戲,大部分都是基於tile地圖的遊戲,如坦克大戰、冒險島、吞食天地等)咱們將會建立一個忍者在沙漠中找西瓜吃的小遊戲。-_- 安全
在第一部分教程中,我將教你們如何使用Tile來建立地圖,怎樣把地圖加到遊戲中,怎麼讓地圖跟隨玩家滾動,以及怎樣使用對象層。 app
在第二部分教程中,我將介紹如何在地圖中建立可碰撞的區域,如何使用tile屬性,如何製做可拾取的物體和動態修改地圖,還有確保忍者不要吃撐了! 框架
若是你尚未準備好的話,你可能須要先從《如何使用cocos2d來製做簡單的iphone遊戲》系列教程開始學起,由於咱們這個教程使用了大量的基本概念,而這些概念均可以從上面的教程中獲取。 iphone
好了,讓咱們玩一玩tile地圖吧! 編輯器
讓咱們首先建立整個工程的骨架,這樣能夠確保從此咱們須要的文件都包含進來了,而且可以跑起來。 ide
所以,啓動XCode,點擊「File\New Project...」,選擇cocos2d Application template,而且把工程命名爲TileGame。 函數
接下來,下載遊戲資源文件。這個資源文件包裏包含了如下內容:
一旦你得到了這些資源,解壓並把它拖到你的工程的「Resources」分組下面。確保複選中「Copy items into destination group’s folder (if needed)」,引用類型爲「Relative to Project」,而後點擊增長。
若是一切順利,全部的文件應該都在你的工程裏了。是時候製做咱們的地圖了!
cocos2d支持使用開源的Tile地圖編輯器建立的TMX格式的地圖。
(做者給出的網址如今打不開了,這是我在另外一個地方找到的。我把它放到個人網盤裏了,而且作了一個連接。若是有人下載不了,請留言。這個tile地圖編輯器是java版的,其實還有一個at版的,可是java版的功能強大一些。可是,你們請注意,做者使用的是qt版本的,因此界面會有一些不一致,但這並不影響程序的使用。)
下載完以後,直接雙擊運行。點擊File\New,而後會出現如下對話框:
在 orientation部分,你能夠選擇Orthogonal(參考: Legend of Zelda)或者Isometric(參考: Disgaea)。咱們這裏將選擇Orthogonal。
接下來,設置地圖的大小。記住,這個大小是以tile爲單位的,而不是以像素爲單位。咱們將建立一個儘可能小的地圖,所以選擇50×50.
最後,你指定每一個tile的寬度和高度。你這裏選擇的寬度和高度要根據你的實際的tile圖片的尺寸來作。這個教程使用的樣例tile的尺寸是32×32,因此在上面的選項中選擇32×32.
接下來,咱們把製做地圖所須要的tile集合導入進來。點擊菜單欄上面的「TileSets」菜單,「New Tileset...」,而後會出現下面的窗口:
爲了得到圖片,點擊Browse按鈕,而後定位到你的TestGame文件夾,選擇 tmw_desert_spacing.png文件,而後加到工程中去。它會基於文件名自動填充Name。而後把TileSet name命名爲「tmw_desert_spacing.png」.同時,設置下面的Tile spacing和Margin都爲1.
你能夠保留寬度和高度爲32×32,由於tile的實際大小也是這麼多。至於margin和spacing,我還沒找到任何好的文檔解釋如何設置這兩個值,下面是個人我的見解:
若是你看看 tmw_desert_spacing.png,你將會看見每個tile都有一個像素的空白邊界圍繞着,這意味着咱們須要把margin和spacing設置爲1.
一旦你選擇ok,你將會看到Tilesets窗口中顯示了一些tiles。如今,你能夠製做地圖了!點擊工具欄上的「Stamp」按鈕。點擊Tile palette中的tile map,而後選擇一個tile,而後再在地圖上的任意位置單擊,你就會看到你選中的tile出如今點中的地方了。
所以,繼續製做地圖吧---充分發揮你的聰明才智!確保增長至少一對建築物在地圖上,由於後面咱們須要一些東西來作碰撞。
記住一些方便的快捷方式:
一旦你完成了地圖的繪製工做,在Layers選項卡的層上面雙擊(如今能夠說是「Layer1」),而後重命名爲「Background」。而後點擊「File\Save」而且保存文件到你的工程的資源文件夾中,而且命名爲「TileMap.tmx」。
後面咱們將會使用這個tmx來作一些有趣的事情,好了,讓咱們把地圖加載到遊戲中去吧!
首先,第一件事情,右鍵點擊Resources,選擇「 Add\Existing Files…」,而後添加TileMap.tmx文件。
打開HelloWorldScene.h,而後添加一些成員變量,而且申明一聲屬性:
而後在HelloWorldScene.m文件中作以下修改:
這裏,咱們調用CCTMXTiledMap類的一些方法,把咱們剛剛建立的地圖文件加載進去。
一些簡明的CCTMXTiledMap的背景知識。它是一個CCNode,你能夠設置它的位置和比例等。這個地圖的孩子是一些層,並且提供了一個幫助函數可讓你經過層的名字獲得層對象--咱們上面就是經過這種方面得到地圖背景的。每個層都是一個CCSpriteSheet的子類,這裏考慮了性能的緣由--可是這也意味着每個層只能有一個tile集。
所以,咱們這裏作的全部這些,就是指向一個tile地圖,而後保存背景層的引用,而且把tile地圖加到HelloWorld層中。
好了,就這麼多!編譯並運行工程,你將會看到地圖的左下角出如今模擬器中。
還不錯!可是,這還不是一個遊戲!咱們還須要三個東西:a)遊戲主角,b)主角初使位置和c)可以移動視圖,這樣就好像是第一視角了。
好了,接下來讓咱們來解決這些問題。
tiled支持兩類層--tile層(就是咱們目前使用的層),還有對象層。
對象層容許你在地圖上圈出一些區域,來指定一些事件的發生。好比,你可能想製做一個區域,在那裏怪物將會跳出來,或者是一個區域,只要進入就會死掉。這咱們這個例子中,咱們將建立一個區域來顯示咱們的遊戲主角。
所以,找到Tiled的菜單,點擊」 Layer\Add Object Group…」,命名爲「Objects」,而後選擇Ok。若是你繪製了地圖,你將會注意到,它並無繪製一個tile,而是畫了一個很難看的灰色矩形,這個矩形咱們以後能夠擴展,使之可以包含多個tiles或者移動它。
咱們只想要選擇一個tile來讓主角顯示。所以,在你的地圖上選擇一個tile。這個區域的大小實際上並無關係,由於咱們僅僅使用x、y座標。
而後,上面的黃色對象上面點右鍵, 取名爲「SpawnPoint",而後選擇Ok:
(添加對象方法很簡單,看到左邊的+號和-號了嗎?一個是增長對象,一個是刪除對象。點中加號之後,用鼠標能夠拖出一個矩陣區域。)
(下面給出一些技巧。如何把一個對象準確放置到Background的空白區域,只須要調整背景的opacity就能夠了)
假設,你能夠作一些奇思妙想。你把對象的類型命名爲cocos2d裏面的class的名字,而後它會爲你建立那個類型(好比CCSprite),可是,我在cocos2d自帶的源代碼裏面代不到這樣的例子。更新:來自GeekAndDad.com的Tyler提供了以前版本的cocos2d裏面使用這種「妙想」的方法,可是,因爲背景有白色,因此被移除了。
無論怎麼說--咱們僅僅把這個類型設置爲空就好了,最後cocos2d會爲咱們建立NSMutableDictionary,咱們能夠從中得到對象的各類屬性,包含x,y座標。
保存地圖,而後返回XCode。在HelloWorldScene.h中作以下修改:
一樣,修改HelloWorldScene.m,代碼以下:
好了,讓咱們先歇會兒,來解釋一下對象層和對象組。首先,注意你經過CCTMXTiledMap對象的objectGroupNamed方法來得到對象層(而不是layerNamed方法)。它返回一個特殊的CCTMXObjectGroup對象。
咱們而後調用CCTMXObjectGroup類的objectNamed方法來得到一個NSMutableDictionary,這個字典包含了關於對象的大量信息,包括x和y座標值,寬度和高度。在這個例子中,咱們只關心x和y座標,所以,咱們提取出這兩個信息,而且設置player的位置。
最後,我想設置這個視圖爲玩家所在的位置。所以,添加下面一個新方法到文件中:
好了,讓我解釋一下。假設這個函數是設置camera的中心。咱們容許用戶傳入地圖上任何x、y座標值--可是若是你仔細想一下,有些東西咱們並不想讓它顯示出來--好比,咱們不想讓屏幕超過地圖的邊界(那些區域僅僅是一個空白區域!)
好比,看看下面這幅圖:
看一下,何時camera的中心會小於winSize.width/2或者winSize.height/2,部分視圖將會在屏幕以外?相似的,咱們須要檢查上面的界限區間,也和咱們這裏的情形同樣。
所以,咱們把這個函數看做是設置camera的視角中心點。然而。。。那不徹底是咱們想要的。在cocos2d裏面有一種方式能夠直接操做一個CCNode的camera,可是那會使事情變得更復雜。咱們須要另外一種替代方法,那就是移動整個層。
看看下面的圖:
想像一個大的地圖,咱們查看從0到winSize.height/width的座標。咱們的視圖的中心點是centerOfView,並且咱們知道咱們要把這個中心設置到哪裏(actualPositon)。所以,爲了使實際的位置和視圖中心相吻合,咱們只須要把地圖往左下角移動便可!
這個能夠經過使實際的位置減去視圖的中心位置來實現,而後設置HelloWorld層到那個點。
唉!太多理論了--讓咱們看點實際的吧!編譯並運行項目,若是一切順利,你將會看到忍者在場景當中,然而視角也移過來了。
咱們已經有一個好的開端了,可是咱們的忍者只是站在那兒不動!這可不像真正的忍者!
讓咱們使忍者動起來吧,只須要讓忍者移動到用戶點擊的地方就好了。在HelloWorldScene.m中增長如下代碼:
首先,在init方法中設置層可以接收touch事件。若是咱們覆蓋registerWithTouchDispatcher方法,來使這個層可以處理目標touch事件。這樣會致使ccTouchBegan和ccTouchEnded方法被調用(注意是單數形式,而不是複數形式的ccTouchesBegan和ccTouchesEnded方法)
你可能會問,爲何我要講這個,由於咱們在 《如何使用cocos2d來製做簡單的iphone遊戲》裏面使用的是ccTouchesBegan和ccTouchesEnded方法。那兩個方法能夠,在這個教程裏用兩種方法均可以。可是,我想向你們介紹一個新方法,由於它有兩個優勢:
無論怎麼說,在咱們的ccTouchEnded裏面,咱們轉換屏幕touch座標爲局部view座標,而後再轉換成GL的座標。這兩個步驟,在新的cocos2d版本中,只須要一步完成,即調用 [self convertToNodeSpace:touchLocation].就能夠了。
這是由於,touch位置只是告訴咱們屏幕視口的座標(好比100,100)。可是,咱們咱們滾動了地圖,這個位置實際可能對應地圖的(800,800)。所以,調用這個方法基於咱們當前層的位置來決定touch的偏移。
接下來,計算出touch點和player的位置之差。咱們必須基於touch位置選擇一個方向,所以,首先,咱們須要計算出是上下移動仍是左右移動。而後,咱們比較正負值,決定具體的方向。
相應的,咱們再調整player的位置,而且設置player的位置爲視口的中心位置,這個在上一節中已經用到了。
更新:注意,咱們不得不添加一個安全檢查,來確保咱們的player不會移到地圖以外!這一點,是Geek&Dad指出來的,謝謝你!
編譯並運行!你如今能夠點擊鼠標,想讓盡者移到哪,它就移到哪兒!
這只是這個教程的一部分。此時,你應該瞭解一些建立tile地圖的基礎了,並且知道如何把它導入到遊戲當中。
這裏有咱們目前爲止用的完整源代碼。
接下,期待第二部分教程吧!在那裏,我將教你們如何在地圖中添加碰撞檢測,若是使咱們的忍者沿着牆壁快樂的奔跑!