Merge pull request #4596 from boyu0/bug2050_tilemap_firstgid_bug

closed #2050: fix tilemap firstgid bug
This commit is contained in:
James Chen 2013-12-30 05:42:19 -08:00
commit 1d8ee016e5
9 changed files with 256 additions and 204 deletions

View File

@ -61,14 +61,12 @@ bool TMXLayer::initWithTilesetInfo(TMXTilesetInfo *tilesetInfo, TMXLayerInfo *la
texture = Director::getInstance()->getTextureCache()->addImage(tilesetInfo->_sourceImage.c_str());
}
if (SpriteBatchNode::initWithTexture(texture, (unsigned int)capacity))
if (SpriteBatchNode::initWithTexture(texture, static_cast<ssize_t>(capacity)))
{
// layerInfo
_layerName = layerInfo->_name;
_layerSize = size;
_tiles = layerInfo->_tiles;
_minGID = layerInfo->_minGID;
_maxGID = layerInfo->_maxGID;
_opacity = layerInfo->_opacity;
setProperties(layerInfo->getProperties());
_contentScaleFactor = Director::getInstance()->getContentScaleFactor();
@ -85,7 +83,7 @@ bool TMXLayer::initWithTilesetInfo(TMXTilesetInfo *tilesetInfo, TMXLayerInfo *la
Point offset = this->calculateLayerOffset(layerInfo->_offset);
this->setPosition(CC_POINT_PIXELS_TO_POINTS(offset));
_atlasIndexArray = ccCArrayNew((unsigned int)totalNumberOfTiles);
_atlasIndexArray = ccCArrayNew(totalNumberOfTiles);
this->setContentSize(CC_SIZE_PIXELS_TO_POINTS(Size(_layerSize.width * _mapTileSize.width, _layerSize.height * _mapTileSize.height)));
@ -100,8 +98,6 @@ bool TMXLayer::initWithTilesetInfo(TMXTilesetInfo *tilesetInfo, TMXLayerInfo *la
TMXLayer::TMXLayer()
:_layerName("")
,_opacity(0)
,_minGID(0)
,_maxGID(0)
,_vertexZvalue(0)
,_useAutomaticVertexZ(false)
,_reusedTile(nullptr)
@ -161,12 +157,12 @@ void TMXLayer::setupTiles()
// Parse cocos2d properties
this->parseInternalProperties();
for (unsigned int y=0; y < _layerSize.height; y++)
for (int y=0; y < _layerSize.height; y++)
{
for (unsigned int x=0; x < _layerSize.width; x++)
for (int x=0; x < _layerSize.width; x++)
{
unsigned int pos = (unsigned int)(x + _layerSize.width * y);
unsigned int gid = _tiles[ pos ];
int pos = static_cast<int>(x + _layerSize.width * y);
int gid = _tiles[ pos ];
// gid are stored in little endian.
// if host is big endian, then swap
@ -178,16 +174,9 @@ void TMXLayer::setupTiles()
if (gid != 0)
{
this->appendTileForGID(gid, Point(x, y));
// Optimization: update min and max GID rendered by the layer
_minGID = MIN(gid, _minGID);
_maxGID = MAX(gid, _maxGID);
}
}
}
CCASSERT( _maxGID >= _tileSet->_firstGid &&
_minGID >= _tileSet->_firstGid, "TMX: Only 1 tileset per layer is supported");
}
// TMXLayer - Properties
@ -231,7 +220,7 @@ void TMXLayer::parseInternalProperties()
}
}
void TMXLayer::setupTileSprite(Sprite* sprite, Point pos, unsigned int gid)
void TMXLayer::setupTileSprite(Sprite* sprite, Point pos, int gid)
{
sprite->setPosition(getPositionAt(pos));
sprite->setVertexZ((float)getVertexZForPos(pos));
@ -252,7 +241,7 @@ void TMXLayer::setupTileSprite(Sprite* sprite, Point pos, unsigned int gid)
sprite->setPosition(Point(getPositionAt(pos).x + sprite->getContentSize().height/2,
getPositionAt(pos).y + sprite->getContentSize().width/2 ) );
unsigned int flag = gid & (kTMXTileHorizontalFlag | kTMXTileVerticalFlag );
int flag = gid & (kTMXTileHorizontalFlag | kTMXTileVerticalFlag );
// handle the 4 diagonally flipped states.
if (flag == kTMXTileHorizontalFlag)
@ -319,7 +308,7 @@ Sprite * TMXLayer::getTileAt(const Point& pos)
CCASSERT(_tiles && _atlasIndexArray, "TMXLayer: the tiles map has been released");
Sprite *tile = nullptr;
unsigned int gid = this->getTileGIDAt(pos);
int gid = this->getTileGIDAt(pos);
// if GID == 0, then no tile is present
if (gid)
@ -348,14 +337,14 @@ Sprite * TMXLayer::getTileAt(const Point& pos)
return tile;
}
unsigned int TMXLayer::getTileGIDAt(const Point& pos, ccTMXTileFlags* flags/* = nullptr*/)
int TMXLayer::getTileGIDAt(const Point& pos, ccTMXTileFlags* flags/* = nullptr*/)
{
CCASSERT(pos.x < _layerSize.width && pos.y < _layerSize.height && pos.x >=0 && pos.y >=0, "TMXLayer: invalid position");
CCASSERT(_tiles && _atlasIndexArray, "TMXLayer: the tiles map has been released");
int idx = (int)(pos.x + pos.y * _layerSize.width);
int idx = static_cast<int>((pos.x + pos.y * _layerSize.width));
// Bits on the far end of the 32-bit global tile ID are used for tile flags
unsigned int tile = _tiles[idx];
int tile = _tiles[idx];
// issue1264, flipped tiles can be changed dynamically
if (flags)
@ -367,42 +356,47 @@ unsigned int TMXLayer::getTileGIDAt(const Point& pos, ccTMXTileFlags* flags/* =
}
// TMXLayer - adding helper methods
Sprite * TMXLayer::insertTileForGID(unsigned int gid, const Point& pos)
Sprite * TMXLayer::insertTileForGID(int gid, const Point& pos)
{
Rect rect = _tileSet->rectForGID(gid);
rect = CC_RECT_PIXELS_TO_POINTS(rect);
intptr_t z = (intptr_t)(pos.x + pos.y * _layerSize.width);
Sprite *tile = reusedTileWithRect(rect);
setupTileSprite(tile, pos, gid);
// get atlas index
ssize_t indexForZ = atlasIndexForNewZ(static_cast<int>(z));
// Optimization: add the quad without adding a child
this->insertQuadFromSprite(tile, indexForZ);
// insert it into the local atlasindex array
ccCArrayInsertValueAtIndex(_atlasIndexArray, (void*)z, indexForZ);
// update possible children
for(const auto &child : _children) {
Sprite* sp = static_cast<Sprite*>(child);
ssize_t ai = sp->getAtlasIndex();
if ( ai >= indexForZ )
{
sp->setAtlasIndex(ai+1);
if (gid != 0 && (static_cast<int>((gid & kFlippedMask)) - _tileSet->_firstGid) >= 0)
{
Rect rect = _tileSet->rectForGID(gid);
rect = CC_RECT_PIXELS_TO_POINTS(rect);
intptr_t z = (intptr_t)(pos.x + pos.y * _layerSize.width);
Sprite *tile = reusedTileWithRect(rect);
setupTileSprite(tile, pos, gid);
// get atlas index
ssize_t indexForZ = atlasIndexForNewZ(static_cast<int>(z));
// Optimization: add the quad without adding a child
this->insertQuadFromSprite(tile, indexForZ);
// insert it into the local atlasindex array
ccCArrayInsertValueAtIndex(_atlasIndexArray, (void*)z, indexForZ);
// update possible children
for(const auto &child : _children) {
Sprite* sp = static_cast<Sprite*>(child);
ssize_t ai = sp->getAtlasIndex();
if ( ai >= indexForZ )
{
sp->setAtlasIndex(ai+1);
}
}
_tiles[z] = gid;
return tile;
}
_tiles[z] = gid;
return tile;
return nullptr;
}
Sprite * TMXLayer::updateTileForGID(unsigned int gid, const Point& pos)
Sprite * TMXLayer::updateTileForGID(int gid, const Point& pos)
{
Rect rect = _tileSet->rectForGID(gid);
rect = Rect(rect.origin.x / _contentScaleFactor, rect.origin.y / _contentScaleFactor, rect.size.width/ _contentScaleFactor, rect.size.height/ _contentScaleFactor);
@ -424,29 +418,34 @@ Sprite * TMXLayer::updateTileForGID(unsigned int gid, const Point& pos)
// used only when parsing the map. useless after the map was parsed
// since lot's of assumptions are no longer true
Sprite * TMXLayer::appendTileForGID(unsigned int gid, const Point& pos)
Sprite * TMXLayer::appendTileForGID(int gid, const Point& pos)
{
Rect rect = _tileSet->rectForGID(gid);
rect = CC_RECT_PIXELS_TO_POINTS(rect);
intptr_t z = (intptr_t)(pos.x + pos.y * _layerSize.width);
Sprite *tile = reusedTileWithRect(rect);
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;
if (gid != 0 && (static_cast<int>((gid & kFlippedMask)) - _tileSet->_firstGid) >= 0)
{
Rect rect = _tileSet->rectForGID(gid);
rect = CC_RECT_PIXELS_TO_POINTS(rect);
intptr_t z = (intptr_t)(pos.x + pos.y * _layerSize.width);
Sprite *tile = reusedTileWithRect(rect);
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;
}
// TMXLayer - atlasIndex and Z
@ -455,7 +454,7 @@ static inline int compareInts(const void * a, const void * b)
return ((*(int*)a) - (*(int*)b));
}
ssize_t TMXLayer::atlasIndexForExistantZ(unsigned int z)
ssize_t TMXLayer::atlasIndexForExistantZ(int z)
{
int key=z;
int *item = (int*)bsearch((void*)&key, (void*)&_atlasIndexArray->arr[0], _atlasIndexArray->num, sizeof(void*), compareInts);
@ -483,23 +482,23 @@ ssize_t TMXLayer::atlasIndexForNewZ(int z)
}
// TMXLayer - adding / remove tiles
void TMXLayer::setTileGID(unsigned int gid, const Point& pos)
void TMXLayer::setTileGID(int gid, const Point& pos)
{
setTileGID(gid, pos, (ccTMXTileFlags)0);
}
void TMXLayer::setTileGID(unsigned int gid, const Point& pos, ccTMXTileFlags flags)
void TMXLayer::setTileGID(int gid, const Point& pos, ccTMXTileFlags flags)
{
CCASSERT(pos.x < _layerSize.width && pos.y < _layerSize.height && pos.x >=0 && pos.y >=0, "TMXLayer: invalid position");
CCASSERT(_tiles && _atlasIndexArray, "TMXLayer: the tiles map has been released");
CCASSERT(gid == 0 || gid >= _tileSet->_firstGid, "TMXLayer: invalid gid" );
ccTMXTileFlags currentFlags;
unsigned int currentGID = getTileGIDAt(pos, &currentFlags);
int currentGID = getTileGIDAt(pos, &currentFlags);
if (currentGID != gid || currentFlags != flags)
{
unsigned gidAndFlags = gid | flags;
int gidAndFlags = gid | flags;
// setting gid=0 is equal to remove the tile
if (gid == 0)
@ -514,7 +513,7 @@ void TMXLayer::setTileGID(unsigned int gid, const Point& pos, ccTMXTileFlags fla
// modifying an existing tile with a non-empty tile
else
{
unsigned int z = (unsigned int)(pos.x + pos.y * _layerSize.width);
int z = pos.x + pos.y * _layerSize.width;
Sprite *sprite = static_cast<Sprite*>(getChildByTag(z));
if (sprite)
{
@ -567,11 +566,11 @@ void TMXLayer::removeTileAt(const Point& pos)
CCASSERT(pos.x < _layerSize.width && pos.y < _layerSize.height && pos.x >=0 && pos.y >=0, "TMXLayer: invalid position");
CCASSERT(_tiles && _atlasIndexArray, "TMXLayer: the tiles map has been released");
unsigned int gid = getTileGIDAt(pos);
int gid = getTileGIDAt(pos);
if (gid)
{
unsigned int z = (unsigned int)(pos.x + pos.y * _layerSize.width);
int z = pos.x + pos.y * _layerSize.width;
ssize_t atlasIndex = atlasIndexForExistantZ(z);
// remove tile from GID map
@ -670,17 +669,17 @@ Point TMXLayer::getPositionForHexAt(const Point& pos)
int TMXLayer::getVertexZForPos(const Point& pos)
{
int ret = 0;
unsigned int maxVal = 0;
int maxVal = 0;
if (_useAutomaticVertexZ)
{
switch (_layerOrientation)
{
case TMXOrientationIso:
maxVal = (unsigned int)(_layerSize.width + _layerSize.height);
ret = (int)(-(maxVal - (pos.x + pos.y)));
maxVal = static_cast<int>(_layerSize.width + _layerSize.height);
ret = static_cast<int>(-(maxVal - (pos.x + pos.y)));
break;
case TMXOrientationOrtho:
ret = (int)(-(_layerSize.height-pos.y));
ret = static_cast<int>(-(_layerSize.height-pos.y));
break;
case TMXOrientationHex:
CCASSERT(0, "TMX Hexa zOrder not supported");

View File

@ -109,8 +109,8 @@ public:
/** returns the tile gid at a given tile coordinate. It also returns the tile flags.
This method requires the the tile map has not been previously released (eg. don't call [layer releaseMap])
*/
unsigned int getTileGIDAt(const Point& tileCoordinate, ccTMXTileFlags* flags = nullptr);
CC_DEPRECATED_ATTRIBUTE unsigned int tileGIDAt(const Point& tileCoordinate, ccTMXTileFlags* flags = nullptr){
int getTileGIDAt(const Point& tileCoordinate, ccTMXTileFlags* flags = nullptr);
CC_DEPRECATED_ATTRIBUTE int tileGIDAt(const Point& tileCoordinate, ccTMXTileFlags* flags = nullptr){
return getTileGIDAt(tileCoordinate, flags);
};
@ -118,7 +118,7 @@ public:
The Tile GID can be obtained by using the method "tileGIDAt" or by using the TMX editor -> Tileset Mgr +1.
If a tile is already placed at that position, then it will be removed.
*/
void setTileGID(unsigned int gid, const Point& tileCoordinate);
void setTileGID(int gid, const Point& tileCoordinate);
/** sets the tile gid (gid = tile global id) at a given tile coordinate.
The Tile GID can be obtained by using the method "tileGIDAt" or by using the TMX editor -> Tileset Mgr +1.
@ -127,7 +127,7 @@ public:
Use withFlags if the tile flags need to be changed as well
*/
void setTileGID(unsigned int gid, const Point& tileCoordinate, ccTMXTileFlags flags);
void setTileGID(int gid, const Point& tileCoordinate, ccTMXTileFlags flags);
/** removes a tile at given tile coordinate */
void removeTileAt(const Point& tileCoordinate);
@ -158,8 +158,8 @@ public:
* @js NA
* @lua NA
*/
inline unsigned int* getTiles() const { return _tiles; };
inline void setTiles(unsigned int* tiles) { _tiles = tiles; };
inline int* getTiles() const { return _tiles; };
inline void setTiles(int* tiles) { _tiles = tiles; };
/** Tileset information for the layer */
inline TMXTilesetInfo* getTileSet() const { return _tileSet; };
@ -170,8 +170,8 @@ public:
};
/** Layer orientation, which is the same as the map orientation */
inline unsigned int getLayerOrientation() const { return _layerOrientation; };
inline void setLayerOrientation(unsigned int orientation) { _layerOrientation = orientation; };
inline int getLayerOrientation() const { return _layerOrientation; };
inline void setLayerOrientation(int orientation) { _layerOrientation = orientation; };
/** properties from the layer. They can be added using Tiled */
inline const ValueMap& getProperties() const { return _properties; };
@ -199,18 +199,18 @@ private:
Point calculateLayerOffset(const Point& offset);
/* optimization methods */
Sprite* appendTileForGID(unsigned int gid, const Point& pos);
Sprite* insertTileForGID(unsigned int gid, const Point& pos);
Sprite* updateTileForGID(unsigned int gid, const Point& pos);
Sprite* appendTileForGID(int gid, const Point& pos);
Sprite* insertTileForGID(int gid, const Point& pos);
Sprite* updateTileForGID(int gid, const Point& pos);
/* The layer recognizes some special properties, like cc_vertez */
void parseInternalProperties();
void setupTileSprite(Sprite* sprite, Point pos, unsigned int gid);
void setupTileSprite(Sprite* sprite, Point pos, int gid);
Sprite* reusedTileWithRect(Rect rect);
int getVertexZForPos(const Point& pos);
// index
ssize_t atlasIndexForExistantZ(unsigned int z);
ssize_t atlasIndexForExistantZ(int z);
ssize_t atlasIndexForNewZ(int z);
protected:
@ -218,10 +218,7 @@ protected:
std::string _layerName;
//! TMX Layer supports opacity
unsigned char _opacity;
unsigned int _minGID;
unsigned int _maxGID;
//! Only used when vertexZ is used
int _vertexZvalue;
bool _useAutomaticVertexZ;
@ -238,11 +235,11 @@ protected:
/** size of the map's tile (could be different from the tile's size) */
Size _mapTileSize;
/** pointer to the map of tiles */
unsigned int* _tiles;
int* _tiles;
/** Tileset information for the layer */
TMXTilesetInfo* _tileSet;
/** Layer orientation, which is the same as the map orientation */
unsigned int _layerOrientation;
int _layerOrientation;
/** properties from the layer. They can be added using Tiled */
ValueMap _properties;
};

View File

@ -122,12 +122,12 @@ TMXTilesetInfo * TMXTiledMap::tilesetForLayer(TMXLayerInfo *layerInfo, TMXMapInf
tileset = *iter;
if (tileset)
{
for( unsigned int y=0; y < size.height; y++ )
for( int y=0; y < size.height; y++ )
{
for( unsigned int x=0; x < size.width; x++ )
for( int x=0; x < size.width; x++ )
{
unsigned int pos = (unsigned int)(x + size.width * y);
unsigned int gid = layerInfo->_tiles[ pos ];
int pos = static_cast<int>(x + size.width * y);
int gid = layerInfo->_tiles[ pos ];
// gid are stored in little endian.
// if host is big endian, then swap

View File

@ -43,8 +43,6 @@ TMXLayerInfo::TMXLayerInfo()
: _name("")
, _tiles(nullptr)
, _ownTiles(true)
, _minGID(100000)
, _maxGID(0)
, _offset(Point::ZERO)
{
}
@ -83,7 +81,7 @@ TMXTilesetInfo::~TMXTilesetInfo()
CCLOGINFO("deallocing TMXTilesetInfo: %p", this);
}
Rect TMXTilesetInfo::rectForGID(unsigned int gid)
Rect TMXTilesetInfo::rectForGID(int gid)
{
Rect rect;
rect.size = _tileSize;
@ -141,7 +139,7 @@ void TMXMapInfo::internalInit(const std::string& tmxFileName, const std::string&
_storingCharacters = false;
_layerAttribs = TMXLayerAttribNone;
_parentElement = TMXPropertyNone;
_currentFirstGID = 0;
_currentFirstGID = -1;
}
bool TMXMapInfo::initWithXML(const std::string& tmxString, const std::string& resourcePath)
{
@ -160,7 +158,8 @@ TMXMapInfo::TMXMapInfo()
, _tileSize(Size::ZERO)
, _layerAttribs(0)
, _storingCharacters(false)
, _currentFirstGID(0)
, _currentFirstGID(-1)
, _recordFirstGID(true)
{
}
@ -265,7 +264,12 @@ void TMXMapInfo::startElement(void *ctx, const char *name, const char **atts)
}
externalTilesetFilename = FileUtils::getInstance()->fullPathForFilename(externalTilesetFilename.c_str());
_currentFirstGID = (unsigned int)attributeDict["firstgid"].asInt();
_currentFirstGID = attributeDict["firstgid"].asInt();
if (_currentFirstGID < 0)
{
_currentFirstGID = 0;
}
_recordFirstGID = false;
tmxMapInfo->parseXMLFile(externalTilesetFilename.c_str());
}
@ -273,17 +277,25 @@ void TMXMapInfo::startElement(void *ctx, const char *name, const char **atts)
{
TMXTilesetInfo *tileset = new TMXTilesetInfo();
tileset->_name = attributeDict["name"].asString();
if (_currentFirstGID == 0)
if (_recordFirstGID)
{
tileset->_firstGid = (unsigned int)attributeDict["firstgid"].asInt();
// unset before, so this is tmx file.
tileset->_firstGid = attributeDict["firstgid"].asInt();
if (tileset->_firstGid < 0)
{
tileset->_firstGid = 0;
}
}
else
{
tileset->_firstGid = _currentFirstGID;
_currentFirstGID = 0;
}
tileset->_spacing = (unsigned int)attributeDict["spacing"].asInt();
tileset->_margin = (unsigned int)attributeDict["margin"].asInt();
tileset->_spacing = attributeDict["spacing"].asInt();
tileset->_margin = attributeDict["margin"].asInt();
Size s;
s.width = attributeDict["tilewidth"].asFloat();
s.height = attributeDict["tileheight"].asFloat();
@ -299,20 +311,17 @@ void TMXMapInfo::startElement(void *ctx, const char *name, const char **atts)
{
TMXLayerInfo* layer = tmxMapInfo->getLayers().back();
Size layerSize = layer->_layerSize;
unsigned int gid = (unsigned int)attributeDict["gid"].asInt();
int gid = attributeDict["gid"].asInt();
int tilesAmount = layerSize.width*layerSize.height;
do
{
// Check the gid is legal or not
CC_BREAK_IF(gid == 0);
if (tilesAmount > 1)
{
// Check the value is all set or not
CC_BREAK_IF(layer->_tiles[tilesAmount - 2] != 0 && layer->_tiles[tilesAmount - 1] != 0);
CC_BREAK_IF(layer->_tiles[tilesAmount - 2] != -1 && layer->_tiles[tilesAmount - 1] != -1);
int currentTileIndex = tilesAmount - layer->_tiles[tilesAmount - 1] - 1;
int currentTileIndex = tilesAmount - layer->_tiles[tilesAmount - 1] - 2;
layer->_tiles[currentTileIndex] = gid;
if (currentTileIndex != tilesAmount - 1)
@ -322,7 +331,7 @@ void TMXMapInfo::startElement(void *ctx, const char *name, const char **atts)
}
else if(tilesAmount == 1)
{
if (layer->_tiles[0] == 0)
if (layer->_tiles[0] == -1)
{
layer->_tiles[0] = gid;
}
@ -333,7 +342,6 @@ void TMXMapInfo::startElement(void *ctx, const char *name, const char **atts)
{
TMXTilesetInfo* info = tmxMapInfo->getTilesets().back();
tmxMapInfo->setParentGID(info->_firstGid + attributeDict["id"].asInt());
//FIXME:XXX Why insert an empty dict?
tmxMapInfo->getTileProperties()[tmxMapInfo->getParentGID()] = Value(ValueMap());
tmxMapInfo->setParentElement(TMXPropertyTile);
}
@ -419,10 +427,8 @@ void TMXMapInfo::startElement(void *ctx, const char *name, const char **atts)
int tilesAmount = layerSize.width*layerSize.height;
int *tiles = (int *) malloc(tilesAmount*sizeof(int));
for (int i = 0; i < tilesAmount; i++)
{
tiles[i] = 0;
}
// set all value to -1
memset(tiles, 0xFF, tilesAmount*sizeof(int));
/* Save the special index in tiles[tilesAmount - 1];
* When we load tiles, we can do this:
@ -432,10 +438,10 @@ void TMXMapInfo::startElement(void *ctx, const char *name, const char **atts)
*/
if (tilesAmount > 1)
{
tiles[tilesAmount - 1] = tilesAmount - 1;
tiles[tilesAmount - 1] = tilesAmount - 2;
}
layer->_tiles = (unsigned int*) tiles;
layer->_tiles = tiles;
}
else if (encoding == "base64")
{
@ -536,9 +542,9 @@ void TMXMapInfo::startElement(void *ctx, const char *name, const char **atts)
}
else if ( tmxMapInfo->getParentElement() == TMXPropertyTile )
{
ValueMapIntKey& dict = tmxMapInfo->getTileProperties().at(tmxMapInfo->getParentGID()).asIntKeyMap();
ValueMap& dict = tmxMapInfo->getTileProperties().at(tmxMapInfo->getParentGID()).asValueMap();
int propertyName = attributeDict["name"].asInt();
std::string propertyName = attributeDict["name"].asString();
dict[propertyName] = attributeDict["value"];
}
}
@ -678,11 +684,11 @@ void TMXMapInfo::endElement(void *ctx, const char *name)
return;
}
layer->_tiles = (unsigned int*) deflated;
layer->_tiles = reinterpret_cast<int*>(deflated);
}
else
{
layer->_tiles = (unsigned int*) buffer;
layer->_tiles = reinterpret_cast<int*>(buffer);
}
tmxMapInfo->setCurrentString("");
@ -693,11 +699,19 @@ void TMXMapInfo::endElement(void *ctx, const char *name)
Size layerSize = layer->_layerSize;
int tilesAmount = layerSize.width * layerSize.height;
//reset the layer->_tiles[tilesAmount - 1]
if (tilesAmount > 1 && layer->_tiles[tilesAmount - 2] == 0)
//set all the tiles unseted to 0
if (tilesAmount > 1 && layer->_tiles[tilesAmount - 2] == -1)
{
for (int i = tilesAmount - layer->_tiles[tilesAmount - 1] - 2; i < tilesAmount; ++i)
{
layer->_tiles[i] = 0;
}
}
else if (layer->_tiles[tilesAmount - 1] == -1)
{
layer->_tiles[tilesAmount - 1] = 0;
}
}
}
@ -721,6 +735,10 @@ void TMXMapInfo::endElement(void *ctx, const char *name)
// The object element has ended
tmxMapInfo->setParentElement(TMXPropertyNone);
}
else if (elementName == "tileset")
{
_recordFirstGID = true;
}
}
void TMXMapInfo::textHandler(void *ctx, const char *ch, int len)

View File

@ -107,12 +107,10 @@ public:
ValueMap _properties;
std::string _name;
Size _layerSize;
unsigned int *_tiles;
int *_tiles;
bool _visible;
unsigned char _opacity;
bool _ownTiles;
unsigned int _minGID;
unsigned int _maxGID;
Point _offset;
};
@ -130,14 +128,14 @@ class CC_DLL TMXTilesetInfo : public Object
{
public:
std::string _name;
unsigned int _firstGid;
Size _tileSize;
unsigned int _spacing;
unsigned int _margin;
int _firstGid;
Size _tileSize;
int _spacing;
int _margin;
//! filename containing the tiles (should be spritesheet / texture atlas)
std::string _sourceImage;
//! size in pixels of the image
Size _imageSize;
Size _imageSize;
public:
/**
* @js ctor
@ -148,7 +146,7 @@ public:
* @lua NA
*/
virtual ~TMXTilesetInfo();
Rect rectForGID(unsigned int gid);
Rect rectForGID(int gid);
};
/** @brief TMXMapInfo contains the information about the map like:
@ -238,8 +236,8 @@ public:
inline void setParentElement(int element) { _parentElement = element; };
/// parent GID
inline unsigned int getParentGID() const { return _parentGID; };
inline void setParentGID(unsigned int gid) { _parentGID = gid; };
inline int getParentGID() const { return _parentGID; };
inline void setParentGID(int gid) { _parentGID = gid; };
/// layer attribs
inline int getLayerAttribs() const { return _layerAttribs; };
@ -296,7 +294,7 @@ protected:
/// parent element
int _parentElement;
/// parent GID
unsigned int _parentGID;
int _parentGID;
/// layer attribs
int _layerAttribs;
/// is storing characters?
@ -312,7 +310,8 @@ protected:
std::string _currentString;
//! tile properties
ValueMapIntKey _tileProperties;
unsigned int _currentFirstGID;
int _currentFirstGID;
bool _recordFirstGID;
};
// end of tilemap_parallax_nodes group

View File

@ -1 +1 @@
f6783c2706a67552d6f361fa099b647158bc79ba
887e2d3869dfa674b390e1373c94937ae965ea6f

View File

@ -1089,7 +1089,10 @@ TMXTilePropertyTest::TMXTilePropertyTest()
addChild(map ,0 ,kTagTileMap);
for(int i=1;i<=20;i++){
log("GID:%i, Properties:%s", i, map->getPropertiesForGID(i).asString().c_str());
for(const auto& value : map->getPropertiesForGID(i).asValueMap())
{
log("GID:%i, Properties:%s, %s", i, value.first.c_str(), value.second.asString().c_str());
}
}
}
@ -1238,6 +1241,42 @@ std::string TMXOrthoFromXMLTest::title() const
{
return "TMX created from XML test";
}
//------------------------------------------------------------------
//
// TMXOrthoXMLFormatTest
//
//------------------------------------------------------------------
TMXOrthoXMLFormatTest::TMXOrthoXMLFormatTest()
{
// this test tests for:
// 1. load xml format tilemap
// 2. gid lower than firstgid is ignored
// 3. firstgid in tsx is ignored, tile property in tsx loaded correctly.
auto map = TMXTiledMap::create("TileMaps/xml-test.tmx");
addChild(map, 0, kTagTileMap);
auto s = map->getContentSize();
log("ContentSize: %f, %f", s.width,s.height);
auto& children = map->getChildren();
for(const auto &node : children) {
auto child = static_cast<SpriteBatchNode*>(node);
child->getTexture()->setAntiAliasTexParameters();
}
for(int i=24;i<=26;i++){
log("GID:%i, Properties:%s", i, map->getPropertiesForGID(i).asValueMap()["name"].asString().c_str());
}
auto action = ScaleBy::create(2, 0.5f);
map->runAction(action);
}
std::string TMXOrthoXMLFormatTest::title() const
{
return "you should see blue, green and yellow in console.";
}
//------------------------------------------------------------------
//
@ -1311,43 +1350,44 @@ enum
static int sceneIdx = -1;
#define MAX_LAYER 28
#define MAX_LAYER 29
static std::function<Layer*()> createFunctions[] = {
CLN(TMXIsoZorder),
CLN(TMXOrthoZorder),
CLN(TMXIsoVertexZ),
CLN(TMXOrthoVertexZ),
CLN(TMXOrthoTest),
CLN(TMXOrthoTest2),
CLN(TMXOrthoTest3),
CLN(TMXOrthoTest4),
CLN(TMXIsoTest),
CLN(TMXIsoTest1),
CLN(TMXIsoTest2),
CLN(TMXUncompressedTest),
CLN(TMXHexTest),
CLN(TMXReadWriteTest),
CLN(TMXTilesetTest),
CLN(TMXOrthoObjectsTest),
CLN(TMXIsoObjectsTest),
CLN(TMXResizeTest),
CLN(TMXIsoMoveLayer),
CLN(TMXOrthoMoveLayer),
CLN(TMXOrthoFlipTest),
CLN(TMXOrthoFlipRunTimeTest),
CLN(TMXOrthoFromXMLTest),
CLN(TMXOrthoXMLFormatTest),
CLN(TileMapTest),
CLN(TileMapEditTest),
CLN(TMXBug987),
CLN(TMXBug787),
CLN(TMXGIDObjectsTest),
};
Layer* createTileMalayer(int nIndex)
{
switch(nIndex)
{
case 0: return new TMXIsoZorder();
case 1: return new TMXOrthoZorder();
case 2: return new TMXIsoVertexZ();
case 3: return new TMXOrthoVertexZ();
case 4: return new TMXOrthoTest();
case 5: return new TMXOrthoTest2();
case 6: return new TMXOrthoTest3();
case 7: return new TMXOrthoTest4();
case 8: return new TMXIsoTest();
case 9: return new TMXIsoTest1();
case 10: return new TMXIsoTest2();
case 11: return new TMXUncompressedTest ();
case 12: return new TMXHexTest();
case 13: return new TMXReadWriteTest();
case 14: return new TMXTilesetTest();
case 15: return new TMXOrthoObjectsTest();
case 16: return new TMXIsoObjectsTest();
case 17: return new TMXResizeTest();
case 18: return new TMXIsoMoveLayer();
case 19: return new TMXOrthoMoveLayer();
case 20: return new TMXOrthoFlipTest();
case 21: return new TMXOrthoFlipRunTimeTest();
case 22: return new TMXOrthoFromXMLTest();
case 23: return new TileMapTest();
case 24: return new TileMapEditTest();
case 25: return new TMXBug987();
case 26: return new TMXBug787();
case 27: return new TMXGIDObjectsTest();
}
return NULL;
return createFunctions[nIndex]();
}
Layer* nextTileMapAction()
@ -1355,10 +1395,7 @@ Layer* nextTileMapAction()
sceneIdx++;
sceneIdx = sceneIdx % MAX_LAYER;
auto layer = createTileMalayer(sceneIdx);
layer->autorelease();
return layer;
return createTileMalayer(sceneIdx);
}
Layer* backTileMapAction()
@ -1366,20 +1403,14 @@ Layer* backTileMapAction()
sceneIdx--;
int total = MAX_LAYER;
if( sceneIdx < 0 )
sceneIdx += total;
auto layer = createTileMalayer(sceneIdx);
layer->autorelease();
sceneIdx += total;
return layer;
return createTileMalayer(sceneIdx);
}
Layer* restartTileMapAction()
{
auto layer = createTileMalayer(sceneIdx);
layer->autorelease();
return layer;
return createTileMalayer(sceneIdx);
}

View File

@ -256,13 +256,20 @@ public:
void flipIt(float dt);
};
class TMXOrthoFromXMLTest : public TileDemo
class TMXOrthoFromXMLTest : public TileDemo
{
public:
TMXOrthoFromXMLTest();
virtual std::string title() const override;
};
class TMXOrthoXMLFormatTest : public TileDemo
{
public:
TMXOrthoXMLFormatTest();
virtual std::string title() const override;
};
class TMXBug987 : public TileDemo
{
public:

View File

@ -18,5 +18,6 @@ public:
// C++ 11
#define CL(__className__) [](){ return __className__::create();}
#define CLN(__className__) [](){ auto obj = new __className__(); obj->autorelease(); return obj; }
#endif