TiledMap+TexturePacker,解决cocos2dx下tiled地图1坑
tiled 做小地图没什么问题。可是要做大型地图应用到cocos2dx中。各种坑。事实上我们仅仅须要简单改动cocos2dx解析代码
1 在编辑器里能够自由加入多个图块, 解析仅仅能弹出断言 仅仅能一个纹理。
==》怎么办,仅仅须要TexturePacker整合成一个纹理集。在解析代码中加入这样的支持就可以,很方便
下面代码 都是我从代码提取出来的 会有点乱。
TMXTiledMap.h 加入
TMXLayer * parseLayer(Texture2D *texture, TMXLayerInfo *layerInfo, TMXMapInfo *mapInfo);//_wb_20140325
std::string _tmxFileName;//_wb_20140325
TMXTiledMap.cpp 改动
在
bool TMXTiledMap::initWithTMXFile(const std::string& tmxFile)
{
加入
_tmxFileName = tmxFile;//_wb_20140325
}
在void TMXTiledMap::buildWithMapInfo(TMXMapInfo* mapInfo)中加入改动
void TMXTiledMap::buildWithMapInfo(TMXMapInfo* mapInfo)
{
_mapSize = mapInfo->getMapSize();
_tileSize = mapInfo->getTileSize();
_mapOrientation = mapInfo->getOrientation();
_objectGroups = mapInfo->getObjectGroups();
_properties = mapInfo->getProperties();
_tileProperties = mapInfo->getTileProperties();
//_wb_20140325
std::string plistfile = _tmxFileName.substr(0, _tmxFileName.find_last_of('.') + 1) + "plist";
SpriteFrameCache::getInstance()->addSpriteFramesWithFile(plistfile.c_str());
std::string pngfile = _tmxFileName.substr(0, _tmxFileName.find_last_of('.') + 1) + "png";
Texture2D *texture = TextureCache::getInstance()->getTextureForKey(pngfile.c_str());
int idx=0;
auto& layers = _layersInfo;
for(const auto &layerInfo : layers) {
if (layerInfo->_visible)
{
TMXLayer *child = parseLayer(texture,layerInfo, mapInfo);
addChild(child, idx, idx);
// update content size with the max size
const Size& childSize = child->getContentSize();
Size currentSize = this->getContentSize();
currentSize.width = std::max( currentSize.width, childSize.width );
currentSize.height = std::max( currentSize.height, childSize.height );
this->setContentSize(currentSize);
idx++;
}
}
}
TMXLayer * TMXTiledMap::parseLayer( Texture2D *texture,TMXLayerInfo *layerInfo, TMXMapInfo *mapInfo)
{
TMXLayer *layer = TMXLayer::create(texture, layerInfo, mapInfo);
// tell the layerinfo to release the ownership of the tiles map.
layerInfo->_ownTiles = false;
layer->setupTiles();
return layer;
}
TMXLayer.h
加入
TMXMapInfo * _mapInfo;//_wb_20140325
static TMXLayer * create( Texture2D *texture, TMXLayerInfo *layerInfo, TMXMapInfo *mapInfo);//_wb_20140325
bool initWithTilesetInfo(Texture2D *texture, TMXLayerInfo *layerInfo, TMXMapInfo *mapInfo);//_wb_20140325
/_wb_20140325
TMXLayer * TMXLayer::create( Texture2D *texture, TMXLayerInfo *layerInfo, TMXMapInfo *mapInfo)
{
TMXLayer *pRet = new TMXLayer();
if (pRet->initWithTilesetInfo(texture,layerInfo, mapInfo))
{
pRet->autorelease();
return pRet;
}
return NULL;
}
//_wb_20140325
bool TMXLayer::initWithTilesetInfo(Texture2D *texture, TMXLayerInfo *layerInfo, TMXMapInfo *mapInfo)
{
// XXX: is 35% a good estimate ?
Size size = layerInfo->_layerSize;
float totalNumberOfTiles = size.width * size.height;
float capacity = totalNumberOfTiles * 0.35f + 1; // 35 percent is oupied ?
if (SpriteBatchNode::initWithTexture(texture, (unsigned int)capacity))
{
// layerInfo
_layerName = layerInfo->_name;
_layerSize = size;
_tiles = layerInfo->_tiles;
_opacity = layerInfo->_opacity;
setProperties(layerInfo->getProperties());
_contentScaleFactor = Director::getInstance()->getContentScaleFactor();
_mapInfo = mapInfo;//_wb_20140325
CC_SAFE_RETAIN(_mapInfo);
// mapInfo
_mapTileSize = mapInfo->getTileSize();
_layerOrientation = mapInfo->getOrientation();
// offset (after layer orientation is set);
Point offset = this->calculateLayerOffset(layerInfo->_offset);
this->setPosition(CC_POINT_PIXELS_TO_POINTS(offset));
_atlasIndexArray = ccCArrayNew(totalNumberOfTiles);
this->setContentSize(CC_SIZE_PIXELS_TO_POINTS(Size(_layerSize.width * _mapTileSize.width, _layerSize.height * _mapTileSize.height)));
_useAutomaticVertexZ = false;
_vertexZvalue = 0;
return true;
}
return false;
}
// TMXLayer - setup Tiles
void TMXLayer::setupTiles()
{
_textureAtlas->getTexture()->setAliasTexParameters();
// Parse cocos2d properties
this->parseInternalProperties();
for (int y=0; y < _layerSize.height; y++)
{
for (int x=0; x < _layerSize.width; x++)
{
int pos = static_cast<int>(x + _layerSize.width * y);
int gid = _tiles[ pos ];
// XXX: gid == 0 --> empty tile
if (gid != 0)
{
this->appendTileForGID(gid, Point(x, y));
}
}
}
}
// since lot's of assumptions are no longer true
Sprite * TMXLayer::appendTileForGID(uint32_t gid, const Point& pos)
{
TMXTilesetInfo* tileSet = _mapInfo->tilesetForGid(static_cast<int>(gid & kTMXFlippedMask));//_wb_20140325
if (tileSet /*&& gid != 0 && (static_cast<int>((gid & kTMXFlippedMask)) - tileSet->_firstGid) >= 0*/)
{
// _wb_20140325 Rect rect = tileSet->getRectForGID(gid);
// _wb_20140325 rect = CC_RECT_PIXELS_TO_POINTS(rect);
intptr_t z = (intptr_t)(pos.x + pos.y * _layerSize.width);
//_wb_20140325 Sprite *tile = reusedTileWithRect(rect);
Sprite * tile = Sprite::createWithSpriteFrameName(tileSet->_sourceImage.c_str()); //_wb_
setupTileSprite(tile ,pos ,gid);
// optimization:
// The difference between appendTileForGID and insertTileforGID is that append is faster, since
// it appends the tile at the end of the texture atlas
ssize_t indexForZ = _atlasIndexArray->num;
// don't add it using the "standard" way.
insertQuadFromSprite(tile, indexForZ);
// append should be after addQuadFromSprite since it modifies the quantity values
ccCArrayInsertValueAtIndex(_atlasIndexArray, (void*)z, indexForZ);
return tile;
}
return nullptr;
}
TMXTilesetInfo改动
TMXTilesetInfo * TMXMapInfo::tilesetForGid(int _gid)//_wb_20140325
{//_wb_20140325
if (!_tilesets.empty())
{
for (auto iter = _tilesets.crbegin(); iter != _tilesets.crend(); ++iter)
{
TMXTilesetInfo* tileset = dynamic_cast<TMXTilesetInfo*>(*iter);
if (tileset->_firstGid == _gid)
{
return tileset;
}
}
}
return nullptr;
}