自拍偷在线精品自拍偷,亚洲欧美中文日韩v在线观看不卡

基于Cocos2D-X的磚塊地圖教程

移動(dòng)開發(fā) Android 游戲開發(fā)
通過文章你將學(xué)習(xí)如何添加磚塊地圖到游戲中,跟著玩家滾動(dòng)地圖,并使用對象圖層。也會(huì)學(xué)到如何使用地圖編輯器去創(chuàng)造磚塊地圖本身。同時(shí)還有如何在地圖上創(chuàng)造碰撞領(lǐng)域,如何使用磚塊屬性,如何創(chuàng)造可收集的道具并動(dòng)態(tài)地修改地圖,以及如何確保你的忍者不會(huì)吃太多東西。

這是Cocos2D-X磚塊地圖教程系列,你將在此創(chuàng)造一款有關(guān)沙漠中的忍者尋找美味的西瓜的簡單游戲。

需要注意的是該教程是關(guān)于Cocos2D-X,即Cocos2D-iPhone的跨平臺C++移植。所以你在此編寫的代碼將適用于iPhone,Android和更多平臺上!

在本系列文章的第一部分中,你將學(xué)習(xí)如何添加磚塊地圖到游戲中,跟著玩家滾動(dòng)地圖,并使用對象圖層。你將學(xué)到如何使用地圖編輯器去創(chuàng)造磚塊地圖本身。

而第二部分是關(guān)于如何在地圖上創(chuàng)造碰撞領(lǐng)域,如何使用磚塊屬性,如何創(chuàng)造可收集的道具并動(dòng)態(tài)地修改地圖,以及如何確保你的忍者不會(huì)吃太多東西。

注:本篇教程類似于Cocos2D-iPhone教程。

讓我們開始創(chuàng)造磚塊地圖吧!

開始

對于這一教程,你需要安裝最新的Cocos2D-X版本(游戲邦注:在寫本篇教程的時(shí)候更新到2.1.4)。如果你還未擁有最新版本的Cocos2D-X,先下載它并在終端運(yùn)行如下命令去安裝模版:

  1. cd ~/Downloads/cocos2d-x-2.1.4 
  2. ./install-templates-xcode.sh -f -u 

然后使用iOS\cocos2d-x\cocos2dx模版在Xcode創(chuàng)造一個(gè)新項(xiàng)目。點(diǎn)擊Next,將項(xiàng)目命名為TileGame,將項(xiàng)目設(shè)置為Universal,點(diǎn)擊Next然后點(diǎn)擊Create。

你將在這一項(xiàng)目中使用ARC,所以如果這是你第一次聽到ARC,我會(huì)鼓勵(lì)你先了解下它。模版并不是默認(rèn)使用ARC,但幸運(yùn)的是,我們能夠輕松地進(jìn)行 修改。前往Edit\Refactor\Convert to Objective-C ARC。往下拉并只選擇文件main.m, AppDelegate.cpp, HelloWorldScene.cpp,然后點(diǎn)擊Check并完成向?qū)У牟襟E。

select targets(from raywenderlich)

select targets(from raywenderlich)

創(chuàng)建并運(yùn)行,然后確保一切都還正常運(yùn)行—-你應(yīng)該能夠看到標(biāo)準(zhǔn)的“你好世界”屏幕。

接下來下載游戲資源的壓縮文件。壓縮文件包含如下內(nèi)容:

你將面向玩家對象使用的精靈。

一些伴隨著cfxr效用所創(chuàng)造的音效(你將會(huì)在教程中用到)。

一些伴隨著Garage Band所創(chuàng)造的背景音樂。

你將用到的一些磚塊設(shè)置—-這將伴隨著你將使用的地圖編輯器,但我認(rèn)為我們能夠更輕松地將其與其它內(nèi)容包含在一起。

一些額外的“特別”磚塊,將在之后進(jìn)行詳細(xì)解釋。

當(dāng)你下載了資源后,打開它并將TileGameResources文件夾拖到項(xiàng)目的Resources群組中。在項(xiàng)目菜單里,右擊 Resources群組,并選擇Add Files to “TileGame”…選擇Resources/TileGameResources文件夾,核實(shí)選中了Copy items into destination group’s folder (if needed)以及Create groups for any added folders,然后點(diǎn)擊完成。

如果一切順利的畫,所有的文件都將出現(xiàn)在你的項(xiàng)目中。

你的項(xiàng)目應(yīng)該如下:

tile game(from raywenderlich)

tile game(from raywenderlich)

現(xiàn)在我們將開始創(chuàng)造地圖!

創(chuàng)造地圖

Cocos2D-X支持基于開放源Tiled Map Editor去創(chuàng)造地圖并將其以TMX格式進(jìn)行保存。

下載Tiled Map Editor。在編寫本篇教程的時(shí)候,其最新版本是0.9.0。

然后運(yùn)行Tiled,前往File\New,并如下填寫對話內(nèi)容:

new map(from raywenderlich)

new map(from raywenderlich)

在定向區(qū)域中,你可以在Orthogonal或Isometric間做出選擇。在此你將選擇Orthogonal。

接下來你將設(shè)置地圖的大小。記住這是在磚塊中,而不是像素中。你將創(chuàng)造一個(gè)較小的地圖,所以在此你應(yīng)該選擇50×50。Tiled將基于像素呈現(xiàn)給 你總體地圖的大小,即在New Map對話的最底部。這是在長度和寬度的基礎(chǔ)上將地圖大小(50個(gè)磚塊)乘以磚塊的大?。?2像素)所計(jì)算出來的。

最后,你將明確寬度和高度。你在此所選擇的是取決于美術(shù)人員所設(shè)置的磚塊。對于本篇教程,你將使用一些伴隨著Tiled編輯器的樣本磚塊,即32×32規(guī)格,選擇它便點(diǎn)擊OK。

接下來你必須添加磚塊設(shè)置去繪制你的地圖。在菜單欄上點(diǎn)擊Map,然后關(guān)掉New Tileset…,并如下填寫對話框內(nèi)容:

new tileset(from raywenderlich)

new tileset(from raywenderlich)

為了獲得圖像,點(diǎn)擊Browse并導(dǎo)航至你自己的TileGame/Resources/TileGameResources文件夾,然后選擇你之前從資源壓縮中下載的tmw_desert_spacing.png文件,并將其添加到項(xiàng)目中。它將自動(dòng)根據(jù)文件名填寫名字。

你可以將寬度和高度設(shè)置為32×32,因?yàn)檫@也是磚塊的大小。對于邊緣和間隔:

邊緣是關(guān)于在Tiled開始尋找真正的磚塊像素前應(yīng)該為當(dāng)前的磚塊略過多少多少像素(包括寬度和高度)。

間隔是關(guān)于Tiled在明確了實(shí)際磚塊像素并轉(zhuǎn)向下一個(gè)磚塊數(shù)據(jù)之后應(yīng)該前進(jìn)多少像素(包括寬度和高度)。

如果你著眼于tmw_desert_spacing.png,你將發(fā)現(xiàn)每個(gè)磚塊都圍繞著一個(gè)1像素的黑色邊緣,這也解釋了邊緣和間隔為1的設(shè)置。

tile(from raywenderlich)

tile(from raywenderlich)

當(dāng)你點(diǎn)擊OK時(shí),你將看到磚塊呈現(xiàn)在Tilesets窗口中?,F(xiàn)在你可以開始繪制了。點(diǎn)擊工具欄的Stamp Brush圖標(biāo),然后點(diǎn)擊地圖上的任何一個(gè)位置去放置一個(gè)磚塊。

tileset(from raywenderlich)

tileset(from raywenderlich)

所以繼續(xù)繪制地圖—-盡可能發(fā)揮創(chuàng)造性!確保添加至少一些建筑到地圖上,因?yàn)槟阍谥髮⑿枰恍┡鲎矁?nèi)容。

tileset(from raywenderlich)

tileset(from raywenderlich)

為了更輕松地繪制內(nèi)容,你可以著眼于一些快捷方法。以下是最常用到的一些方法:

你可以在Tileset選擇器中圍繞著一系列磚塊拖曳一個(gè)盒子,并同時(shí)放下多個(gè)相鄰的磚塊。

你可以通過View\Zoom In和View\Zoom Out進(jìn)行放大和縮小。

z鍵將在基于Stamp Brush工具編輯地圖時(shí)進(jìn)行旋轉(zhuǎn)。

在一些新功能中你可能會(huì)注意到Mini-map。這是一個(gè)很棒的功能,它讓你能夠看到一個(gè)迷你地圖!著眼于我在Mini-map最下方的迷宮中的糟糕嘗試。紅色盒子代表你在主要編輯窗口中看到的區(qū)域。

tileset(from raywenderlich)

tileset(from raywenderlich)

當(dāng)你在閱讀下一個(gè)區(qū)域中的滾動(dòng)時(shí)牢牢記住這一Mini-map視圖。

需要注意的是這一教程的資源是出現(xiàn)在地圖前的——所以如果你很懶的話便可以直接利用它。如果你這么做,你應(yīng)該在Tiled打開地圖并明確它是如何設(shè)置的。

當(dāng)你完成地圖的繪制時(shí),在Layers視圖中雙擊Tile Layer,將名字改為Background。然后點(diǎn)擊File\Save,并將文件保存到TileGame項(xiàng)目中的TileGame \Resources\TileGameResources,將文件命名為TileMap.tmx,并覆蓋現(xiàn)有的文件。

你將在之后使用Tiled做其它事,但是現(xiàn)在讓我們將這一地圖帶進(jìn)游戲中!

添加Tiled地圖到Cocos2D-X場景中

打開HelloWorldScene.h,在#include “cocos2d.h”之后添加如下內(nèi)容:

  1. using namespace cocos2d; 

這能指導(dǎo)編輯器去使用cocos2d命名空間,所以你不需要為所有內(nèi)容加上cocos2d的前綴。

然后添加以下內(nèi)容到類定義中,即在花括號之后:

  1. private
  2. CCTMXTiledMap *_tileMap; 
  3. CCTMXLayer *_background; 

這創(chuàng)造了一個(gè)實(shí)例變量去追蹤磚塊地圖本身,并創(chuàng)造了另一個(gè)實(shí)例變量去追蹤地圖的背景層。你將在之后學(xué)到更多有關(guān)磚塊地圖層面的內(nèi)容。

接下來,用如下內(nèi)容換掉HelloWorldScene.cpp:

  1. CCTMXObjectGroup *objectGroup = _tileMap->objectGroupNamed(“Objects”); 
  2.  
  3. if(objectGroup == NULL){ 
  4. CCLog(“tile map has no objects object layer”); 
  5. return false
  6.  
  7. CCDictionary *spawnPoint = objectGroup->objectNamed(“SpawnPoint”); 
  8.  
  9. int x = ((CCString)*spawnPoint->valueForKey(“x”)).intValue(); 
  10. int y = ((CCString)*spawnPoint->valueForKey(“y”)).intValue(); 
  11.  
  12. _player = new CCSprite(); 
  13. _player->initWithFile(“Player.png”); 
  14. _player->setPosition(ccp(x,y)); 
  15.  
  16. this->addChild(_player); 
  17. this->setViewPointCenter(_player->getPosition()); 

最后一行有個(gè)預(yù)兆——但不要擔(dān)心,你很快就能到達(dá)那里。

讓我們暫停一會(huì)并解釋對象層面和對象群組。首先注意你是通過在CCTMXTiledMap對象中(而不是layerNamed)通過objectGroupNamed方法檢索對象層面。它返回了一個(gè)特殊的CCTMXObjectGroup對象。

然后objectGroup調(diào)用了objectNamed方法去獲得一個(gè)CCDictionary,并包含了一些有關(guān)對象的有用信息,如x和y軸,寬度和高度。在教程的這一部分,你需要關(guān)心的便是x和y軸,將其設(shè)置為玩家精靈的位置。

在代碼塊的最后你設(shè)置了視圖去明確玩家的位置。所以現(xiàn)在添加如下內(nèi)容到HelloWorldScene.h中:

  1. // In the public section 
  2. void setViewPointCenter(CCPoint position); 

并添加一個(gè)新方法到HelloWorldScene.cpp(在文件的最下方最好):

  1. void HelloWorld::setViewPointCenter(CCPoint position) { 
  2.  
  3. CCSize winSize = CCDirector::sharedDirector()->getWinSize(); 
  4.  
  5. int x = MAX(position.x, winSize.width/2); 
  6. int y = MAX(position.y, winSize.height/2); 
  7. x = MIN(x, (_tileMap->getMapSize().width * this->_tileMap->getTileSize().width) – winSize.width / 2); 
  8. y = MIN(y, (_tileMap->getMapSize().height * _tileMap->getTileSize().height) – winSize.height/2); 
  9. CCPoint actualPosition = ccp(x, y); 
  10.  
  11. CCPoint centerOfView = ccp(winSize.width/2, winSize.height/2); 
  12. CCPoint viewPoint = ccpSub(centerOfView, actualPosition); 
  13. this->setPosition(viewPoint); 

這是關(guān)于磚塊的解釋。想象這一函數(shù)設(shè)置了攝像機(jī)的中心位置。它讓用戶能夠進(jìn)入地圖中x,y軸的任何位置—-但是你有可能不想呈現(xiàn)出某些點(diǎn),如你可能不想要屏幕超過地圖的邊緣(那么它便只會(huì)呈現(xiàn)出黑邊?。?/p>

如下圖:

diagram(from raywenderlich)

diagram(from raywenderlich)

如果攝像機(jī)的中心小于winSize.width/2或winSize.height/2,那么部分視角是否會(huì)脫離屏幕?同樣的,檢查最上方的界限也很重要,這也是setViewPointCenter所做的。

到目前為止這一函數(shù)被當(dāng)成設(shè)置了攝像機(jī)所面對的中心位置。然而,這并不是它真正做的。這是在Cocos2D-X中操控CCNode的攝像機(jī)的一種方法,但使用它會(huì)比你將使用的解決方法(移動(dòng)整個(gè)層面)更復(fù)雜。

著眼于這一圖解:

diagram(from raywenderlich)

diagram(from raywenderlich)想象一個(gè)大世界,你將著眼于坐標(biāo)軸,即從0到winSize.height/width。你的視圖的中心是 centerOfView,你便能清楚自己想要以哪里為中心(actualPosition)。所以為了用實(shí)際位置去匹配視圖中心位置,你需要做的便是向 下傾斜地圖!

通過從視圖中心減去實(shí)際位置你便能夠做到這點(diǎn),然后將HelloWorld層面設(shè)為該位置。

說了這么多理論,是時(shí)候執(zhí)行它們了!創(chuàng)建并運(yùn)行項(xiàng)目,如果一切運(yùn)行正常,你將在屏幕上看到忍者,并且視圖會(huì)不斷移動(dòng)去呈現(xiàn)他的行動(dòng)。

simulator(from raywenderlich)

simulator(from raywenderlich)

讓忍者移動(dòng)

這是個(gè)好的開始,但是你的忍者還只是站在那里!這并不像真正的忍者。你將朝著用戶敲打的方向移動(dòng)忍者而讓他動(dòng)起來。添加如下代碼到HelloWorldScene.h的公共部分:

  1. void registerWithTouchDispatcher(); 
  2. void setPlayerPosition(CCPoint position); 
  3. bool ccTouchBegan(CCTouch *touch, CCEvent *event); 
  4. void ccTouchEnded(CCTouch *touch, CCEvent *event); 

然后打開HelloWorldScene.cpp并將如下代碼添加到init:

  1. this->setTouchEnabled(true); 

這將層面設(shè)置為可碰觸的,所以它將關(guān)注于碰觸事件。接下來添加如下方法到文件最底端:

  1. #pragma mark – handle touches 
  2.  
  3. void HelloWorld::registerWithTouchDispatcher() { 
  4. CCDirector::sharedDirector()->getTouchDispatcher()->addTargetedDelegate(this, 0, true); 
  5.  
  6. bool HelloWorld::ccTouchBegan(CCTouch *touch, CCEvent *event) 
  7. return true
  8.  
  9. void HelloWorld::setPlayerPosition(CCPoint position) { 
  10. _player->setPosition(position); 
  11.  
  12. void HelloWorld::ccTouchEnded(CCTouch *touch, CCEvent *event) 
  13. CCPoint touchLocation = touch->getLocationInView(); 
  14. touchLocation = CCDirector::sharedDirector()->convertToGL(touchLocation); 
  15. touchLocation = this->convertToNodeSpace(touchLocation); 
  16.  
  17. CCPoint playerPos = _player->getPosition(); 
  18. CCPoint diff = ccpSub(touchLocation, playerPos); 
  19.  
  20. if ( abs(diff.x) > abs(diff.y) ) { 
  21. if (diff.x > 0) { 
  22. playerPos.x += _tileMap->getTileSize().width; 
  23. else { 
  24. playerPos.x -= _tileMap->getTileSize().width; 
  25. else { 
  26. if (diff.y > 0) { 
  27. playerPos.y += _tileMap->getTileSize().height; 
  28. else { 
  29. playerPos.y -= _tileMap->getTileSize().height; 
  30.  
  31. // safety check on the bounds of the map 
  32. if (playerPos.x <= (_tileMap->getMapSize().width * _tileMap->getTileSize().width) && 
  33. playerPos.y <= (_tileMap->getMapSize().height * _tileMap->getTileSize().height) && 
  34. playerPos.y >= 0 && 
  35. playerPos.x >= 0 ) 
  36. this->setPlayerPosition(playerPos); 
  37.  
  38. this->setViewPointCenter(_player->getPosition()); 

在此你覆蓋了registerWithTouchDispatcher方法去處理目標(biāo)碰觸事件。這將導(dǎo)致ccTouchBegan/ccTouchEnded方法(單數(shù)情況)被調(diào)用,而不是ccTouchesBegan/ccTouchesEnded方法(復(fù)數(shù)情況)。

你可能會(huì)好奇單數(shù)情況和復(fù)數(shù)情況有什么區(qū)別。不過在這種情況下我們沒有必要去弄清楚這些問題。但是我還是想向所有人介紹這一方法,因?yàn)樗鼛в?個(gè)主要優(yōu)勢:

“你不需要處理NSSets,調(diào)度程序能夠區(qū)分它們。每次調(diào)用你將獲得一個(gè)UITouch。”

“你可以通過在ccTouchBegan返回YES而要求一個(gè)UITouch。要求碰觸的更新只會(huì)被發(fā)送到要求它們的委托中。所以如果你刪除/結(jié)束/取消更新,你就需要確保它是你的碰觸。這將讓你無需在執(zhí)行多點(diǎn)碰觸時(shí)做各種檢查。”

不管怎樣,在你的ccTouchEnded位置上,你像往常那樣將位置轉(zhuǎn)換成視圖坐標(biāo)軸,然后再轉(zhuǎn)換成GL坐標(biāo)軸。而新任務(wù)便是你調(diào)用了this->convertToNodeSpace(touchLocation)。

這是因?yàn)榕鲇|位置將提供給你用戶在視口中輕敲的坐標(biāo)軸(例如100,100)。但是你可能已經(jīng)滾動(dòng)了地圖,所以它將匹配(800,800)的位置。所以調(diào)用這一方法將基于你如何移動(dòng)層面而抵消碰觸。

接下來你將明確碰觸點(diǎn)和玩家位置的區(qū)別。你將基于碰觸選擇一個(gè)方向,所以首先你應(yīng)該決定是上下移動(dòng)還是左右移動(dòng)。然后你將判斷是正數(shù)還是復(fù)數(shù)而進(jìn)行上下移動(dòng)。

你將相對地調(diào)整玩家位置,然后將視圖中心設(shè)置為玩家的位置,這是你在上部分便寫下的內(nèi)容!

注意你必須添加一個(gè)安全檢查以確保不會(huì)將玩家?guī)щx地圖外部!

所以創(chuàng)建并運(yùn)行項(xiàng)目,然后嘗試它!現(xiàn)在你應(yīng)該能夠輕敲屏幕去移動(dòng)忍者了!

simulator(from raywenderlich)

simulator(from raywenderlich)

最后

這時(shí)候你已經(jīng)知道如何創(chuàng)造地圖并將其整合到游戲中了。而在第二部分教程中你將進(jìn)一步學(xué)習(xí)如何添加碰撞檢測到地圖中以避免忍者能夠輕松地穿越墻壁。

責(zé)任編輯:閆佳明 來源: gamerboom
相關(guān)推薦

2011-12-12 10:40:08

Cocos2d-X游戲開發(fā)開發(fā)環(huán)境

2012-04-17 12:58:44

Cocos2D-X

2013-05-22 15:49:46

2012-04-17 12:44:38

cocos2d-x

2012-04-17 12:38:46

cocos2d-x

2013-04-16 10:02:47

cocos2d-x懶人Android開發(fā)

2014-07-31 16:57:30

2013-05-22 14:38:44

iOS開發(fā)Cocos2d-x坐標(biāo)系統(tǒng)

2013-06-03 17:04:20

CocoStudioCocos2D-X添加CocoStudi

2015-07-21 16:25:24

2015-07-17 10:38:21

教程COCOS射箭游戲

2012-02-19 20:10:23

Cocos2d-x fCocos2dWindows Pho

2012-04-17 13:12:00

2012-04-17 10:06:08

cocos2d-x

2012-04-17 10:59:31

cocos2d-x

2012-04-17 12:47:27

cocos2d-x

2013-06-13 15:09:37

Cocos2D-X手機(jī)游戲開發(fā)手機(jī)游戲引擎

2012-04-16 15:20:41

cocos2d-x

2013-11-13 16:31:32

Cocos2d-x

2012-05-09 10:09:57

Cocos2d-xAndroidiOS
點(diǎn)贊
收藏

51CTO技術(shù)棧公眾號