转载请标明:转载自【小枫栏目】,博文链接:http://blog.csdn.net/rexuefengye/article/details/10517641
在开发游戏的过程中,特别是地图编辑器中,需要利用最少的资源,实现最丰富的地形地貌。
另外,就是在一些策略类游戏里经常用到的战争迷雾,如图
战争迷雾制作原理参考以下文章: http://bbs.9ria.com/thread-157487-1-1.html
现在,打开我们的Tiled地图编辑器,新建一个地图:【新建】->【新建文件】,地图宽为10,地图高为10。
然后将瓦片图素拖动到图块区域,添加图块,宽高分别为128像素,边距和间距都为0:
然后,最重要的一步来了!选中第一个图素,涂满地图,效果如下:
HelloWorldScene.h
#ifndef __HELLOWORLD_SCENE_H__ #define __HELLOWORLD_SCENE_H__ #include "cocos2d.h" #include "TiledFourCell.h" using namespace cocos2d; class HelloWorld : public cocos2d::CCLayerColor { public: // Method 'init' in cocos2d-x returns bool, instead of 'id' in cocos2d-iphone (an object pointer) virtual bool init(); // there's no 'id' in cpp, so we recommend to return the class instance pointer static cocos2d::CCScene* scene(); // a selector callback void menuCloseCallback(CCObject* pSender); // preprocessor macro for "static create()" constructor ( node() deprecated ) CREATE_FUNC(HelloWorld); //add code virtual bool ccTouchBegan( CCTouch *pTouch, CCEvent *pEvent ); virtual void registerWithTouchDispatcher( void ); CCPoint getMapTiledPos( CCTMXTiledMap* map, CCPoint pos); void changeCloudTiled4( CCTMXLayer* layer, CCPoint pos ); void setGidByTotalNum( CCTMXLayer* layer, CCPoint pos, int iTotalNum ); TiledFourCell* getCellByTiledPos( CCPoint pos ); void changeCloudTiled8( CCTMXLayer* layer, CCPoint pos ); void changeCloudTiled1( CCTMXLayer* layer, CCPoint pos ); void changeCloudTiled2( CCTMXLayer* layer, CCPoint pos ); private: CCTMXTiledMap* cloudMap; CCDictionary* tiledCellsDict; // 瓦片坐标和瓦片顶点对象 键值对 CCArray* gidsArray; // 瓦片图片gid与瓦片顶点数值总和对应 }; #endif // __HELLOWORLD_SCENE_H__HelloWorldScene.cpp
#include "HelloWorldScene.h" #include "SimpleAudioEngine.h" using namespace cocos2d; using namespace CocosDenshion; CCScene* HelloWorld::scene() { // 'scene' is an autorelease object CCScene *scene = CCScene::create(); // 'layer' is an autorelease object HelloWorld *layer = HelloWorld::create(); // add layer as a child to scene scene->addChild(layer); // return the scene return scene; } // on "init" you need to initialize your instance bool HelloWorld::init() { ////////////////////////////// // 1. super init first if ( !CCLayer::init() ) { return false; } CCLayerColor::initWithColor(ccc4(255, 255, 255, 255)); cloudMap = CCTMXTiledMap::create("blackCloud.tmx"); this->addChild(cloudMap); this->setTouchEnabled(true); gidsArray = CCArray::createWithCapacity(16); tiledCellsDict = CCDictionary::create(); gidsArray->retain(); tiledCellsDict->retain(); /* 瓦片地图使用4X4的图片,每张小图片对应的数值如下: 0 4 8 12 1 5 9 13 2 6 10 14 3 7 11 15 以上数值为瓦片格子的数据值。 瓦片图素从1开始计数,如下: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 比如数据值4,对应的瓦片图素是2;数据值10,对应的瓦片图素是11。 */ /* 以数据值为索引,可以取得瓦片图素 */ gidsArray->addObject(CCInteger::create(1));//顶点总和0,对应图素ID为1 gidsArray->addObject(CCInteger::create(5));// 顶点总和1,对应图素ID为5 gidsArray->addObject(CCInteger::create(9));// 顶点总和2,对应图素ID为9 gidsArray->addObject(CCInteger::create(13));// 顶点总和3,对应图素ID为13 gidsArray->addObject(CCInteger::create(2));// 顶点总和4,对应图素ID为2 gidsArray->addObject(CCInteger::create(6));// 顶点总和5,对应图素ID为6 gidsArray->addObject(CCInteger::create(10)); gidsArray->addObject(CCInteger::create(14)); gidsArray->addObject(CCInteger::create(3)); gidsArray->addObject(CCInteger::create(7)); gidsArray->addObject(CCInteger::create(11)); gidsArray->addObject(CCInteger::create(15)); gidsArray->addObject(CCInteger::create(4)); gidsArray->addObject(CCInteger::create(8)); gidsArray->addObject(CCInteger::create(12)); gidsArray->addObject(CCInteger::create(16)); return true; } //void HelloWorld::menuCloseCallback(CCObject* pSender) //{ // CCDirector::sharedDirector()->end(); // //#if (CC_TARGET_PLATFORM == CC_PLATFORM_IOS) // exit(0); //#endif //} bool HelloWorld::ccTouchBegan(CCTouch *pTouch, CCEvent *pEvent) { CCLog("helloworld"); CCPoint tiledMapPos = getMapTiledPos( cloudMap, CCDirector::sharedDirector()->convertToGL(pTouch->getLocationInView())); CCLOG("TiledMapPos x = %f, y = %f", tiledMapPos.x, tiledMapPos.y); CCTMXLayer* cloudLayer = cloudMap->layerNamed("cloudLayer"); /* 设置当前瓦片的数据值,以及设置旁白瓦片的数据值 */ changeCloudTiled4(cloudLayer, tiledMapPos); changeCloudTiled8(cloudLayer, ccp(tiledMapPos.x + 1, tiledMapPos.y)); changeCloudTiled1(cloudLayer, ccp(tiledMapPos.x, tiledMapPos.y + 1)); changeCloudTiled2(cloudLayer, ccp(tiledMapPos.x + 1, tiledMapPos.y + 1)); return true; } void HelloWorld::registerWithTouchDispatcher() { CCDirector* pDirector = CCDirector::sharedDirector(); pDirector->getTouchDispatcher()->addTargetedDelegate(this, 0, true); } CCPoint HelloWorld::getMapTiledPos(CCTMXTiledMap *map, CCPoint pos) { CCSize mapSize = map->getMapSize(); CCSize tiledSize = map->getTileSize(); int iMapHeight = mapSize.height * tiledSize.height; /* pos为笛卡尔坐标系的坐标,所以y轴需要修正 */ int x = pos.x / tiledSize.width; int y = (iMapHeight - pos.y) / tiledSize.height; return CCPointMake(x, y); } void HelloWorld::changeCloudTiled4(CCTMXLayer *layer,CCPoint pos) { TiledFourCell* cell = getCellByTiledPos(pos); /* 数值4,在瓦片右下角 */ cell->setiRightBottom(4); /* 根据瓦片4个顶点之和设置地图瓦片的图片 */ setGidByTotalNum(layer, pos, cell->getiTotalNum()); } void HelloWorld::changeCloudTiled8(CCTMXLayer *layer, CCPoint pos) { TiledFourCell* cell = getCellByTiledPos(pos); cell->setiLeftBottom(8); setGidByTotalNum(layer, pos, cell->getiTotalNum()); } void HelloWorld::changeCloudTiled1(CCTMXLayer *layer, CCPoint pos) { TiledFourCell* cell = getCellByTiledPos(pos); cell->setiRightTop(1); setGidByTotalNum(layer, pos, cell->getiTotalNum()); } void HelloWorld::changeCloudTiled2(CCTMXLayer *layer, CCPoint pos) { TiledFourCell* cell = getCellByTiledPos(pos); cell->setiLeftTop(2); setGidByTotalNum(layer, pos, cell->getiTotalNum()); } void HelloWorld::setGidByTotalNum( CCTMXLayer* layer, CCPoint pos, int iTotalNum ) { CCSize mapSize = cloudMap->getMapSize(); /* 避免超出范围 */ if(pos.x < 0 || pos. y < 0 || pos.x >= mapSize.width || pos.y >= mapSize.height) { return; } /* iTotalNum是瓦片的4个顶点数据值的总和,通过这个值获得对应的瓦片图素 */ CCInteger* gidInt = (CCInteger*)gidsArray->objectAtIndex(iTotalNum); /* 用新的瓦片图素替换pos坐标上的瓦片图素 */ layer->setTileGID(gidInt->getValue(), pos); } TiledFourCell* HelloWorld::getCellByTiledPos( CCPoint pos ) { CCSize mapSize = cloudMap->getMapSize(); /* 瓦片坐标原本是二维坐标,转换为一维数值 */ int index = mapSize.width * pos.x + pos.y; /* 取得瓦片的顶点数据对象 */ const char* keyCh = CCString::createWithFormat("%d", index)->getCString(); CCObject* obj = tiledCellsDict->objectForKey(keyCh); TiledFourCell* cell = NULL; if(obj == NULL) { /* 如果该瓦片没有顶点数据对象,则创建一个,顶点数据值默认都为0 */ cell = TiledFourCell::create(); tiledCellsDict->setObject(cell, keyCh); } else { cell = (TiledFourCell*)obj; } return cell; }创建瓦片类TiledFourCell
TiledFourCell.h
// // TiledFourCell.h // Fog // // Created by IDEA-MAC03 on 13-8-29. // // #ifndef __Fog__TiledFourCell__ #define __Fog__TiledFourCell__ #include "cocos2d.h" using namespace cocos2d; class TiledFourCell : public CCNode { public: CREATE_FUNC(TiledFourCell); virtual bool init(); void setiLeftTop(int _iLeftTop); int getiLeftTop(); void setiLeftBottom(int _iLeftBottom); int getiLeftBottom(); void setiRightTop(int _iRightTop); int getiRightTop(); void setiRightBottom(int _iRightBottom); int getiRightBottom(); /* 获取顶点值的总和 */ int getiTotalNum(); private: int iLeftTop; // 左上角 int iLeftBottom;// 左下角 int iRightTop; // 右上角 int iRightBottom; // 右下角 }; #endif /* defined(__Fog__TiledFourCell__) */
TiledFourCell.cpp
// // Created by IDEA-MAC03 on 13-8-29. // // #include "TiledFourCell.h" bool TiledFourCell::init() { iLeftTop = 0; iLeftBottom = 0; iRightTop = 0; iRightBottom = 0; return true; } void TiledFourCell::setiLeftTop(int _iLeftTop) { iLeftTop = _iLeftTop; } int TiledFourCell::getiLeftTop() { return iLeftTop; } void TiledFourCell::setiLeftBottom(int _iLeftBottom) { iLeftBottom = _iLeftBottom; } int TiledFourCell::getiLeftBottom() { return iLeftBottom; } void TiledFourCell::setiRightTop(int _iRightTop) { iRightTop = _iRightTop; } int TiledFourCell::getiRightTop() { return iRightTop; } void TiledFourCell::setiRightBottom(int _iRightBottom) { iRightBottom = _iRightBottom; } int TiledFourCell::getiRightBottom() { return iRightBottom; } int TiledFourCell::getiTotalNum() { return (iLeftTop + iLeftBottom + iRightTop + iRightBottom); }
详细教程可参考:http://www.benmutou.com/blog/archives/485
代码下载:http://download.csdn.net/detail/my183100521/6032981