Merge pull request #182 from halx99/leve-one-tmxlayermap

Only leave one TMXLayer & TMXTileMap
This commit is contained in:
HALX99 2020-08-28 03:13:36 -07:00 committed by GitHub
commit 0653090a62
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
26 changed files with 490 additions and 3965 deletions

View File

@ -93,6 +93,8 @@ bool FastTMXLayer::initWithTilesetInfo(TMXTilesetInfo *tilesetInfo, TMXLayerInfo
// mapInfo
_mapTileSize = mapInfo->getTileSize();
_layerOrientation = mapInfo->getOrientation();
_staggerAxis = mapInfo->getStaggerAxis();
_staggerIndex = mapInfo->getStaggerIndex();
// offset (after layer orientation is set);
Vec2 offset = this->calculateLayerOffset(layerInfo->_offset);
@ -321,6 +323,57 @@ void FastTMXLayer::setupTiles()
_screenTileCount = (int)(_screenGridSize.width * _screenGridSize.height);
if (!_tileSet->_animationInfo.empty()) {
/// FastTMXLayer: anim support
for (int y = 0; y < _layerSize.height; y++)
{
for (int x = 0; x < _layerSize.width; x++)
{
int newX = x;
// fix correct render ordering in Hexagonal maps when stagger axis == x
if (_staggerAxis == TMXStaggerAxis_X && _layerOrientation == TMXOrientationHex)
{
if (_staggerIndex == TMXStaggerIndex_Odd)
{
if (x >= _layerSize.width / 2)
newX = (x - std::ceil(_layerSize.width / 2)) * 2 + 1;
else
newX = x * 2;
}
else {
// TMXStaggerIndex_Even
if (x >= static_cast<int>(_layerSize.width / 2))
newX = (x - static_cast<int>(_layerSize.width / 2)) * 2;
else
newX = x * 2 + 1;
}
}
int pos = static_cast<int>(newX + _layerSize.width * y);
int gid = _tiles[pos];
// gid are stored in little endian.
// if host is big endian, then swap
//if( o == CFByteOrderBigEndian )
// gid = CFSwapInt32( gid );
/* We support little endian.*/
// FIXME:: gid == 0 --> empty tile
if (gid != 0)
{
if (_tileSet->_animationInfo.find(gid) != _tileSet->_animationInfo.end())
{
_animTileCoord[gid].push_back(Vec2(newX, y));
}
}
}
}
if (hasTileAnimation())
{
_tileAnimManager = new TMXTileAnimManager(this);
}
}
}
Mat4 FastTMXLayer::tileToNodeTransform()
@ -910,5 +963,97 @@ std::string FastTMXLayer::getDescription() const
return StringUtils::format("<FastTMXLayer | tag = %d, size = %d,%d>", _tag, (int)_mapTileSize.width, (int)_mapTileSize.height);
}
TMXTileAnimManager::TMXTileAnimManager(FastTMXLayer* layer)
{
_layer = layer;
for (const auto& p : *_layer->getAnimTileCoord())
{
for (auto tilePos : p.second)
{
_tasks.pushBack(TMXTileAnimTask::create(_layer, _layer->getTileSet()->_animationInfo.at(p.first), tilePos));
}
}
}
TMXTileAnimManager* TMXTileAnimManager::create(FastTMXLayer* layer)
{
TMXTileAnimManager* ret = new (std::nothrow) TMXTileAnimManager(layer);
if (ret)
{
ret->autorelease();
return ret;
}
CC_SAFE_DELETE(ret);
return nullptr;
}
void TMXTileAnimManager::startAll()
{
if (_started || _tasks.empty())
return;
_started = true;
for (auto& task : _tasks)
{
task->start();
}
}
void TMXTileAnimManager::stopAll()
{
if (!_started)
return;
_started = false;
for (auto& task : _tasks)
{
task->stop();
}
}
TMXTileAnimTask::TMXTileAnimTask(FastTMXLayer* layer, TMXTileAnimInfo* animation, const Vec2& tilePos)
{
_layer = layer;
_animation = animation;
_frameCount = static_cast<uint32_t>(_animation->_frames.size());
_tilePosition = tilePos;
std::stringstream ss;
ss << "TickAnimOnTilePos(" << _tilePosition.x << "," << _tilePosition.y << ")";
_key = ss.str();
}
void TMXTileAnimTask::tickAndScheduleNext(float dt)
{
setCurrFrame();
_layer->getParent()->scheduleOnce(CC_CALLBACK_1(TMXTileAnimTask::tickAndScheduleNext, this), _animation->_frames[_currentFrame]._duration / 1000.0f, _key);
}
void TMXTileAnimTask::start()
{
_isRunning = true;
tickAndScheduleNext(0.0f);
}
void TMXTileAnimTask::stop()
{
_isRunning = false;
_layer->getParent()->unschedule(_key);
}
void TMXTileAnimTask::setCurrFrame()
{
_layer->setTileGID(_animation->_frames[_currentFrame]._tileID, _tilePosition);
_currentFrame = (_currentFrame + 1) % _frameCount;
}
TMXTileAnimTask* TMXTileAnimTask::create(FastTMXLayer* layer, TMXTileAnimInfo* animation, const Vec2& tilePos)
{
TMXTileAnimTask* ret = new (std::nothrow) TMXTileAnimTask(layer, animation, tilePos);
if (ret)
{
ret->autorelease();
return ret;
}
CC_SAFE_DELETE(ret);
return nullptr;
}
NS_CC_END

View File

@ -37,6 +37,7 @@ NS_CC_BEGIN
class TMXMapInfo;
class TMXLayerInfo;
class TMXTilesetInfo;
class TMXTileAnimManager;
class Texture2D;
class Sprite;
@ -275,10 +276,29 @@ public:
virtual void draw(Renderer *renderer, const Mat4& transform, uint32_t flags) override;
void removeChild(Node* child, bool cleanup = true) override;
/** Map from gid of animated tile to its instance.
*
* @return Map from gid of animated tile to its instance.
*/
const std::unordered_map<uint32_t, std::vector<Vec2>>* getAnimTileCoord() {
return &_animTileCoord;
}
bool hasTileAnimation() const {
return !_animTileCoord.empty();
}
TMXTileAnimManager* getTileAnimManager() const {
return _tileAnimManager;
}
CC_CONSTRUCTOR_ACCESS:
bool initWithTilesetInfo(TMXTilesetInfo* tilesetInfo, TMXLayerInfo* layerInfo, TMXMapInfo* mapInfo);
protected:
virtual void setOpacity(uint8_t opacity) override;
bool initWithTilesetInfo(TMXTilesetInfo *tilesetInfo, TMXLayerInfo *layerInfo, TMXMapInfo *mapInfo);
void updateTiles(const Rect& culledRect);
Vec2 calculateLayerOffset(const Vec2& offset);
@ -315,9 +335,16 @@ protected:
TMXTilesetInfo* _tileSet = nullptr;
/** Layer orientation, which is the same as the map orientation */
int _layerOrientation = FAST_TMX_ORIENTATION_ORTHO;
int _staggerAxis = TMXStaggerAxis_Y;
int _staggerIndex = TMXStaggerIndex_Even;
/** properties from the layer. They can be added using Tiled */
ValueMap _properties;
/** map from gid of animated tile to its instance. Also useful for optimization*/
std::unordered_map<uint32_t, std::vector<Vec2>> _animTileCoord;
/** pointer to the tile animation manager of this layer */
TMXTileAnimManager* _tileAnimManager = nullptr;
Texture2D *_texture = nullptr;
/** container for sprite children. map<index, pair<sprite, gid> > */
@ -356,6 +383,69 @@ protected:
backend::UniformLocation _alphaValueLocation;
};
/** @brief TMXTileAnimTask represents the frame-tick task of an animated tile.
* It is a assistant class for TMXTileAnimTicker.
*/
class CC_DLL TMXTileAnimTask : public Ref
{
public:
TMXTileAnimTask(FastTMXLayer* layer, TMXTileAnimInfo* animation, const Vec2& tilePos);
static TMXTileAnimTask* create(FastTMXLayer* layer, TMXTileAnimInfo* animation, const Vec2& tilePos);
/** start the animation task */
void start();
/** stop the animation task */
void stop();
bool isRunning() const {
return _isRunning;
}
protected:
/** set texture of tile to current frame */
void setCurrFrame();
/** tick to next frame and schedule next tick */
void tickAndScheduleNext(float dt);
bool _isRunning = false;
/** key of schedule task for specific animated tile */
std::string _key;
FastTMXLayer* _layer = nullptr;
/** position of the animated tile */
Vec2 _tilePosition;
/** AnimationInfo on this tile */
TMXTileAnimInfo* _animation = nullptr;
/** Index of the frame that should be drawn currently */
uint32_t _currentFrame = 0;
uint32_t _frameCount = 0;
};
/** @brief TMXTileAnimManager controls all tile animation of a layer.
*/
class CC_DLL TMXTileAnimManager : public Ref
{
public:
static TMXTileAnimManager* create(FastTMXLayer* layer);
explicit TMXTileAnimManager(FastTMXLayer* layer);
/** start all tile animations */
void startAll();
/** stop all tile animations */
void stopAll();
/** get vector of tasks */
const Vector<TMXTileAnimTask*>& getTasks() const {
return _tasks;
}
protected:
bool _started = false;
/** vector contains all tasks of this layer */
Vector<TMXTileAnimTask*> _tasks;
FastTMXLayer* _layer = nullptr;
};
// @API compatible
typedef FastTMXLayer TMXLayer;
// end of tilemap_parallax_nodes group
/// @}
NS_CC_END

View File

@ -72,6 +72,8 @@ bool FastTMXTiledMap::initWithTMXFile(const std::string& tmxFile)
CCASSERT( !mapInfo->getTilesets().empty(), "FastTMXTiledMap: Map not found. Please check the filename.");
buildWithMapInfo(mapInfo);
_tmxFile = tmxFile;
return true;
}
@ -192,6 +194,8 @@ void FastTMXTiledMap::buildWithMapInfo(TMXMapInfo* mapInfo)
idx++;
}
}
_layerCount = idx;
}
// public
@ -257,4 +261,22 @@ std::string FastTMXTiledMap::getDescription() const
return StringUtils::format("<FastTMXTiledMap | Tag = %d, Layers = %d", _tag, static_cast<int>(_children.size()));
}
void FastTMXTiledMap::setTileAnimEnabled(bool enabled)
{
for (auto& child : _children)
{
FastTMXLayer* layer = dynamic_cast<FastTMXLayer*>(child);
if (layer)
{
if (layer->hasTileAnimation())
{
if (enabled)
layer->getTileAnimManager()->startAll();
else
layer->getTileAnimManager()->stopAll();
}
}
}
}
NS_CC_END

View File

@ -201,7 +201,18 @@ public:
virtual std::string getDescription() const override;
protected:
/** Set all tile animations enabled or not.
* animations are not enabled by default
*/
void setTileAnimEnabled(bool enabled);
CC_DEPRECATED_ATTRIBUTE int getLayerNum() const { return getLayerCount(); }
int getLayerCount() const { return _layerCount; }
const std::string& getResourceFile() const { return _tmxFile; }
CC_CONSTRUCTOR_ACCESS:
/**
* @js ctor
*/
@ -218,6 +229,7 @@ protected:
/** initializes a TMX Tiled Map with a TMX formatted XML string and a path to TMX resources */
bool initWithXML(const std::string& tmxString, const std::string& resourcePath);
protected:
FastTMXLayer * parseLayer(TMXLayerInfo *layerInfo, TMXMapInfo *mapInfo);
TMXTilesetInfo * tilesetForLayer(TMXLayerInfo *layerInfo, TMXMapInfo *mapInfo);
void buildWithMapInfo(TMXMapInfo* mapInfo);
@ -236,6 +248,9 @@ protected:
//! tile properties
ValueMapIntKey _tileProperties;
int _layerCount = 0;
std::string _tmxFile;
private:
CC_DISALLOW_COPY_AND_ASSIGN(FastTMXTiledMap);
@ -244,5 +259,7 @@ private:
// end of tilemap_parallax_nodes group
/** @} */
// @API compatible
typedef FastTMXTiledMap TMXTiledMap;
NS_CC_END

View File

@ -1,849 +0,0 @@
/****************************************************************************
Copyright (c) 2008-2010 Ricardo Quesada
Copyright (c) 2010-2012 cocos2d-x.org
Copyright (c) 2011 Zynga Inc.
Copyright (c) 2013-2016 Chukong Technologies Inc.
Copyright (c) 2017-2018 Xiamen Yaji Software Co., Ltd.
http://www.cocos2d-x.org
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
****************************************************************************/
#include "2d/CCTMXLayer.h"
#include "2d/CCTMXTiledMap.h"
#include "2d/CCSprite.h"
#include "base/CCDirector.h"
#include "base/ccUTF8.h"
#include "renderer/CCTextureCache.h"
#include "renderer/ccShaders.h"
#include "renderer/backend/Program.h"
#include "renderer/backend/ProgramState.h"
NS_CC_BEGIN
// TMXLayer - init & alloc & dealloc
TMXLayer * TMXLayer::create(TMXTilesetInfo *tilesetInfo, TMXLayerInfo *layerInfo, TMXMapInfo *mapInfo)
{
TMXLayer *ret = new (std::nothrow) TMXLayer();
if (ret->initWithTilesetInfo(tilesetInfo, layerInfo, mapInfo))
{
ret->autorelease();
return ret;
}
CC_SAFE_DELETE(ret);
return nullptr;
}
bool TMXLayer::initWithTilesetInfo(TMXTilesetInfo *tilesetInfo, TMXLayerInfo *layerInfo, TMXMapInfo *mapInfo)
{
// FIXME:: is 35% a good estimate ?
Size size = layerInfo->_layerSize;
float totalNumberOfTiles = size.width * size.height;
float capacity = totalNumberOfTiles * 0.35f + 1; // 35 percent is occupied ?
Texture2D *texture = nullptr;
if( tilesetInfo )
{
texture = Director::getInstance()->getTextureCache()->addImage(tilesetInfo->_sourceImage);
}
if (nullptr == texture)
return false;
if (SpriteBatchNode::initWithTexture(texture, static_cast<ssize_t>(capacity)))
{
// layerInfo
_layerName = layerInfo->_name;
_layerSize = size;
_tiles = layerInfo->_tiles;
_opacity = layerInfo->_opacity;
setProperties(layerInfo->getProperties());
_contentScaleFactor = Director::getInstance()->getContentScaleFactor();
// tilesetInfo
_tileSet = tilesetInfo;
CC_SAFE_RETAIN(_tileSet);
// mapInfo
_mapTileSize = mapInfo->getTileSize();
_layerOrientation = mapInfo->getOrientation();
_staggerAxis = mapInfo->getStaggerAxis();
_staggerIndex = mapInfo->getStaggerIndex();
_hexSideLength = mapInfo->getHexSideLength();
// offset (after layer orientation is set);
Vec2 offset = this->calculateLayerOffset(layerInfo->_offset);
this->setPosition(CC_POINT_PIXELS_TO_POINTS(offset));
_atlasIndexArray = ccCArrayNew(totalNumberOfTiles);
float width = 0;
float height = 0;
if (_layerOrientation == TMXOrientationHex) {
if (_staggerAxis == TMXStaggerAxis_X) {
height = _mapTileSize.height * (_layerSize.height + 0.5);
width = (_mapTileSize.width + _hexSideLength) * ((int)(_layerSize.width / 2)) + _mapTileSize.width * ((int)_layerSize.width % 2);
} else {
width = _mapTileSize.width * (_layerSize.width + 0.5);
height = (_mapTileSize.height + _hexSideLength) * ((int)(_layerSize.height / 2)) + _mapTileSize.height * ((int)_layerSize.height % 2);
}
} else {
width = _layerSize.width * _mapTileSize.width;
height = _layerSize.height * _mapTileSize.height;
}
this->setContentSize(CC_SIZE_PIXELS_TO_POINTS(Size(width, height)));
_useAutomaticVertexZ = false;
_vertexZvalue = 0;
return true;
}
return false;
}
TMXLayer::TMXLayer()
:_layerName("")
,_opacity(0)
,_vertexZvalue(0)
,_useAutomaticVertexZ(false)
,_reusedTile(nullptr)
,_atlasIndexArray(nullptr)
,_contentScaleFactor(1.0f)
,_layerSize(Size::ZERO)
,_mapTileSize(Size::ZERO)
,_tiles(nullptr)
,_tileSet(nullptr)
,_layerOrientation(TMXOrientationOrtho)
,_staggerAxis(TMXStaggerAxis_Y)
,_staggerIndex(TMXStaggerIndex_Even)
,_hexSideLength(0)
{}
TMXLayer::~TMXLayer()
{
CC_SAFE_RELEASE(_tileSet);
CC_SAFE_RELEASE(_reusedTile);
if (_atlasIndexArray)
{
ccCArrayFree(_atlasIndexArray);
_atlasIndexArray = nullptr;
}
CC_SAFE_FREE(_tiles);
}
void TMXLayer::releaseMap()
{
if (_tiles)
{
free(_tiles);
_tiles = nullptr;
}
if (_atlasIndexArray)
{
ccCArrayFree(_atlasIndexArray);
_atlasIndexArray = nullptr;
}
}
// TMXLayer - setup Tiles
void TMXLayer::setupTiles()
{
// Optimization: quick hack that sets the image size on the tileset
_tileSet->_imageSize = _textureAtlas->getTexture()->getContentSizeInPixels();
// By default all the tiles are aliased
// pros:
// - easier to render
// cons:
// - difficult to scale / rotate / etc.
_textureAtlas->getTexture()->setAliasTexParameters();
//CFByteOrder o = CFByteOrderGetCurrent();
// Parse cocos2d properties
this->parseInternalProperties();
for (int y=0; y < _layerSize.height; y++)
{
for (int x=0; x < _layerSize.width; x++)
{
int newX = x;
// fix correct render ordering in Hexagonal maps when stagger axis == x
if (_staggerAxis == TMXStaggerAxis_X && _layerOrientation == TMXOrientationHex)
{
if (_staggerIndex == TMXStaggerIndex_Odd)
{
if (x >= _layerSize.width/2)
newX = (x - std::ceil(_layerSize.width/2)) * 2 + 1;
else
newX = x * 2;
} else {
// TMXStaggerIndex_Even
if (x >= static_cast<int>(_layerSize.width/2))
newX = (x - static_cast<int>(_layerSize.width/2)) * 2;
else
newX = x * 2 + 1;
}
}
int pos = static_cast<int>(newX + _layerSize.width * y);
int gid = _tiles[ pos ];
// gid are stored in little endian.
// if host is big endian, then swap
//if( o == CFByteOrderBigEndian )
// gid = CFSwapInt32( gid );
/* We support little endian.*/
// FIXME:: gid == 0 --> empty tile
if (gid != 0)
{
this->appendTileForGID(gid, Vec2(newX, y));
}
}
}
}
// TMXLayer - Properties
Value TMXLayer::getProperty(const std::string& propertyName) const
{
if (_properties.find(propertyName) != _properties.end())
return _properties.at(propertyName);
return Value();
}
void TMXLayer::parseInternalProperties()
{
// if cc_vertex=automatic, then tiles will be rendered using vertexz
auto vertexz = getProperty("cc_vertexz");
if (!vertexz.isNull())
{
std::string vertexZStr = vertexz.asString();
// If "automatic" is on, then parse the "cc_alpha_func" too
if (vertexZStr == "automatic")
{
_useAutomaticVertexZ = true;
auto alphaFuncVal = getProperty("cc_alpha_func");
float alphaFuncValue = alphaFuncVal.asFloat();
setProgramStateWithRegistry(backend::ProgramType::POSITION_TEXTURE_COLOR_ALPHA_TEST, nullptr);
auto& pipelineDescriptor = _quadCommand.getPipelineDescriptor();
auto& vertexShader = pipelineDescriptor.programState->getProgram()->getVertexShader();
auto alphaValueLocation = pipelineDescriptor.programState->getUniformLocation("u_alpha_value");
pipelineDescriptor.programState->setUniform(alphaValueLocation, &alphaFuncValue, sizeof(alphaFuncValue));
}
else
{
_vertexZvalue = vertexz.asInt();
}
}
}
void TMXLayer::setupTileSprite(Sprite* sprite, const Vec2& pos, uint32_t gid)
{
sprite->setPosition(getPositionAt(pos));
sprite->setPositionZ((float)getVertexZForPos(pos));
sprite->setAnchorPoint(Vec2::ZERO);
sprite->setOpacity(_opacity);
//issue 1264, flip can be undone as well
sprite->setFlippedX(false);
sprite->setFlippedY(false);
sprite->setRotation(0.0f);
sprite->setAnchorPoint(Vec2(0,0));
// Rotation in tiled is achieved using 3 flipped states, flipping across the horizontal, vertical, and diagonal axes of the tiles.
if (gid & kTMXTileDiagonalFlag)
{
// put the anchor in the middle for ease of rotation.
sprite->setAnchorPoint(Vec2(0.5f,0.5f));
sprite->setPosition(getPositionAt(pos).x + sprite->getContentSize().height/2,
getPositionAt(pos).y + sprite->getContentSize().width/2 );
auto flag = gid & (kTMXTileHorizontalFlag | kTMXTileVerticalFlag );
// handle the 4 diagonally flipped states.
if (flag == kTMXTileHorizontalFlag)
{
sprite->setRotation(90.0f);
}
else if (flag == kTMXTileVerticalFlag)
{
sprite->setRotation(270.0f);
}
else if (flag == (kTMXTileVerticalFlag | kTMXTileHorizontalFlag) )
{
sprite->setRotation(90.0f);
sprite->setFlippedX(true);
}
else
{
sprite->setRotation(270.0f);
sprite->setFlippedX(true);
}
}
else
{
if (gid & kTMXTileHorizontalFlag)
{
sprite->setFlippedX(true);
}
if (gid & kTMXTileVerticalFlag)
{
sprite->setFlippedY(true);
}
}
}
Sprite* TMXLayer::reusedTileWithRect(const Rect& rect)
{
if (! _reusedTile)
{
_reusedTile = Sprite::createWithTexture(_textureAtlas->getTexture(), rect);
_reusedTile->setBatchNode(this);
_reusedTile->retain();
}
else
{
// FIXME: HACK: Needed because if "batch node" is nil,
// then the Sprite'squad will be reset
_reusedTile->setBatchNode(nullptr);
// Re-init the sprite
_reusedTile->setTextureRect(rect, false, rect.size);
// restore the batch node
_reusedTile->setBatchNode(this);
}
return _reusedTile;
}
// TMXLayer - obtaining tiles/gids
Sprite * TMXLayer::getTileAt(const Vec2& 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");
Sprite *tile = nullptr;
int gid = this->getTileGIDAt(pos);
// if GID == 0, then no tile is present
if (gid)
{
int z = (int)(pos.x + pos.y * _layerSize.width);
tile = static_cast<Sprite*>(this->getChildByTag(z));
// tile not created yet. create it
if (! tile)
{
Rect rect = _tileSet->getRectForGID(gid);
rect = CC_RECT_PIXELS_TO_POINTS(rect);
tile = Sprite::createWithTexture(this->getTexture(), rect);
tile->setBatchNode(this);
tile->setPosition(getPositionAt(pos));
tile->setPositionZ((float)getVertexZForPos(pos));
tile->setAnchorPoint(Vec2::ZERO);
tile->setOpacity(_opacity);
ssize_t indexForZ = atlasIndexForExistantZ(z);
this->addSpriteWithoutQuad(tile, static_cast<int>(indexForZ), z);
}
}
return tile;
}
uint32_t TMXLayer::getTileGIDAt(const Vec2& pos, TMXTileFlags* 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");
ssize_t idx = static_cast<int>(((int) pos.x + (int) pos.y * _layerSize.width));
// Bits on the far end of the 32-bit global tile ID are used for tile flags
uint32_t tile = _tiles[idx];
// issue1264, flipped tiles can be changed dynamically
if (flags)
{
*flags = (TMXTileFlags)(tile & kTMXFlipedAll);
}
return (tile & kTMXFlippedMask);
}
// TMXLayer - adding helper methods
Sprite * TMXLayer::insertTileForGID(uint32_t gid, const Vec2& pos)
{
if (gid != 0 && (static_cast<int>((gid & kTMXFlippedMask)) - _tileSet->_firstGid) >= 0)
{
Rect rect = _tileSet->getRectForGID(gid);
rect = CC_RECT_PIXELS_TO_POINTS(rect);
intptr_t z = (intptr_t)((int) pos.x + (int) 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);
auto ai = sp->getAtlasIndex();
if ( ai >= indexForZ )
{
sp->setAtlasIndex(ai+1);
}
}
_tiles[z] = gid;
return tile;
}
return nullptr;
}
Sprite * TMXLayer::updateTileForGID(uint32_t gid, const Vec2& pos)
{
Rect rect = _tileSet->getRectForGID(gid);
rect = Rect(rect.origin.x / _contentScaleFactor, rect.origin.y / _contentScaleFactor, rect.size.width/ _contentScaleFactor, rect.size.height/ _contentScaleFactor);
int z = (int)((int) pos.x + (int) pos.y * _layerSize.width);
Sprite *tile = reusedTileWithRect(rect);
setupTileSprite(tile ,pos ,gid);
// get atlas index
auto indexForZ = atlasIndexForExistantZ(z);
tile->setAtlasIndex(static_cast<unsigned int>(indexForZ) );
tile->setDirty(true);
tile->updateTransform();
_tiles[z] = gid;
return tile;
}
intptr_t TMXLayer::getZForPos(const Vec2& pos) const
{
intptr_t z = -1;
// fix correct render ordering in Hexagonal maps when stagger axis == x
if (_staggerAxis == TMXStaggerAxis_X && _layerOrientation == TMXOrientationHex)
{
if (_staggerIndex == TMXStaggerIndex_Odd)
{
if (((int)pos.x % 2) == 0)
z = pos.x / 2 + pos.y * _layerSize.width;
else
z = pos.x / 2 + std::ceil(_layerSize.width / 2) + pos.y * _layerSize.width;
} else {
// TMXStaggerIndex_Even
if (((int)pos.x % 2) == 1)
z = pos.x / 2 + pos.y * _layerSize.width;
else
z = pos.x / 2 + std::floor(_layerSize.width / 2) + pos.y * _layerSize.width;
}
}
else
{
z = (pos.x + pos.y * _layerSize.width);
}
CCASSERT(z != -1, "Invalid Z");
return z;
}
// used only when parsing the map. useless after the map was parsed
// since lot's of assumptions are no longer true
Sprite * TMXLayer::appendTileForGID(uint32_t gid, const Vec2& pos)
{
if (gid != 0 && (static_cast<int>((gid & kTMXFlippedMask)) - _tileSet->_firstGid) >= 0)
{
Rect rect = _tileSet->getRectForGID(gid);
rect = CC_RECT_PIXELS_TO_POINTS(rect);
// Z could be just an integer that gets incremented each time it is called.
// but that wouldn't work on layers with empty tiles.
// and it is IMPORTANT that Z returns an unique and bigger number than the previous one.
// since _atlasIndexArray must be ordered because `bsearch` is used to find the GID for
// a given Z. (github issue #16512)
intptr_t z = getZForPos(pos);
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);
// Validation for issue #16512
CCASSERT(_atlasIndexArray->num == 1 ||
_atlasIndexArray->arr[_atlasIndexArray->num-1] > _atlasIndexArray->arr[_atlasIndexArray->num-2], "Invalid z for _atlasIndexArray");
return tile;
}
return nullptr;
}
// TMXLayer - atlasIndex and Z
static inline int compareInts(const void * a, const void * b)
{
const int ia = *(int*)a;
const int ib = *(int*)b;
return (ia-ib);
}
ssize_t TMXLayer::atlasIndexForExistantZ(int z)
{
int key=z;
int *item = (int*)bsearch((void*)&key, (void*)&_atlasIndexArray->arr[0], _atlasIndexArray->num, sizeof(void*), compareInts);
CCASSERT(item, "TMX atlas index not found. Shall not happen");
ssize_t index = ((size_t)item - (size_t)_atlasIndexArray->arr) / sizeof(void*);
return index;
}
ssize_t TMXLayer::atlasIndexForNewZ(int z)
{
// FIXME:: This can be improved with a sort of binary search
ssize_t i=0;
for (i=0; i< _atlasIndexArray->num ; i++)
{
ssize_t val = (size_t) _atlasIndexArray->arr[i];
if (z < val)
{
break;
}
}
return i;
}
// TMXLayer - adding / remove tiles
void TMXLayer::setTileGID(uint32_t gid, const Vec2& pos)
{
setTileGID(gid, pos, (TMXTileFlags)0);
}
void TMXLayer::setTileGID(uint32_t gid, const Vec2& pos, TMXTileFlags 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 || (int)gid >= _tileSet->_firstGid, "TMXLayer: invalid gid" );
TMXTileFlags currentFlags;
uint32_t currentGID = getTileGIDAt(pos, &currentFlags);
if (currentGID != gid || currentFlags != flags)
{
uint32_t gidAndFlags = gid | flags;
// setting gid=0 is equal to remove the tile
if (gid == 0)
{
removeTileAt(pos);
}
// empty tile. create a new one
else if (currentGID == 0)
{
insertTileForGID(gidAndFlags, pos);
}
// modifying an existing tile with a non-empty tile
else
{
int z = (int) pos.x + (int) pos.y * _layerSize.width;
Sprite *sprite = static_cast<Sprite*>(getChildByTag(z));
if (sprite)
{
Rect rect = _tileSet->getRectForGID(gid);
rect = CC_RECT_PIXELS_TO_POINTS(rect);
sprite->setTextureRect(rect, false, rect.size);
if (flags)
{
setupTileSprite(sprite, sprite->getPosition(), gidAndFlags);
}
_tiles[z] = gidAndFlags;
}
else
{
updateTileForGID(gidAndFlags, pos);
}
}
}
}
void TMXLayer::addChild(Node* /*child*/, int /*zOrder*/, int /*tag*/)
{
CCASSERT(0, "addChild: is not supported on TMXLayer. Instead use setTileGID:at:/tileAt:");
}
void TMXLayer::removeChild(Node* node, bool cleanup)
{
Sprite *sprite = (Sprite*)node;
// allows removing nil objects
if (! sprite)
{
return;
}
CCASSERT(_children.contains(sprite), "Tile does not belong to TMXLayer");
ssize_t atlasIndex = sprite->getAtlasIndex();
ssize_t zz = (ssize_t)_atlasIndexArray->arr[atlasIndex];
_tiles[zz] = 0;
ccCArrayRemoveValueAtIndex(_atlasIndexArray, atlasIndex);
SpriteBatchNode::removeChild(sprite, cleanup);
}
void TMXLayer::removeTileAt(const Vec2& 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");
int gid = getTileGIDAt(pos);
if (gid)
{
int z = pos.x + pos.y * _layerSize.width;
ssize_t atlasIndex = atlasIndexForExistantZ(z);
// remove tile from GID map
_tiles[z] = 0;
// remove tile from atlas position array
ccCArrayRemoveValueAtIndex(_atlasIndexArray, atlasIndex);
// remove it from sprites and/or texture atlas
Sprite *sprite = (Sprite*)getChildByTag(z);
if (sprite)
{
SpriteBatchNode::removeChild(sprite, true);
}
else
{
_textureAtlas->removeQuadAtIndex(atlasIndex);
// update possible children
for(const auto &obj : _children) {
Sprite* child = static_cast<Sprite*>(obj);
auto ai = child->getAtlasIndex();
if ( ai >= atlasIndex )
{
child->setAtlasIndex(ai-1);
}
}
}
}
}
//CCTMXLayer - obtaining positions, offset
Vec2 TMXLayer::calculateLayerOffset(const Vec2& pos)
{
Vec2 ret;
switch (_layerOrientation)
{
case TMXOrientationOrtho:
ret.set( pos.x * _mapTileSize.width, -pos.y *_mapTileSize.height);
break;
case TMXOrientationIso:
ret.set((_mapTileSize.width /2) * (pos.x - pos.y),
(_mapTileSize.height /2 ) * (-pos.x - pos.y));
break;
case TMXOrientationHex:
{
if(_staggerAxis == TMXStaggerAxis_Y)
{
int diffX = (_staggerIndex == TMXStaggerIndex_Even) ? _mapTileSize.width/2 : 0;
ret.set(pos.x * _mapTileSize.width + diffX, -pos.y * (_mapTileSize.height - (_mapTileSize.width - _hexSideLength) / 2));
}
else if(_staggerAxis == TMXStaggerAxis_X)
{
int diffY = (_staggerIndex == TMXStaggerIndex_Odd) ? _mapTileSize.height/2 : 0;
ret.set(pos.x * (_mapTileSize.width - (_mapTileSize.width - _hexSideLength) / 2), -pos.y * _mapTileSize.height + diffY);
}
break;
}
case TMXOrientationStaggered:
{
float diffX = 0;
if ((int)std::abs(pos.y) % 2 == 1)
{
diffX = _mapTileSize.width/2;
}
ret.set(pos.x * _mapTileSize.width + diffX,
(-pos.y) * _mapTileSize.height/2);
}
break;
}
return ret;
}
Vec2 TMXLayer::getPositionAt(const Vec2& pos)
{
Vec2 ret;
switch (_layerOrientation)
{
case TMXOrientationOrtho:
ret = getPositionForOrthoAt(pos);
break;
case TMXOrientationIso:
ret = getPositionForIsoAt(pos);
break;
case TMXOrientationHex:
ret = getPositionForHexAt(pos);
break;
case TMXOrientationStaggered:
ret = getPositionForStaggeredAt(pos);
break;
}
ret = CC_POINT_PIXELS_TO_POINTS( ret );
return ret;
}
Vec2 TMXLayer::getPositionForOrthoAt(const Vec2& pos)
{
return Vec2(pos.x * _mapTileSize.width,
(_layerSize.height - pos.y - 1) * _mapTileSize.height);
}
Vec2 TMXLayer::getPositionForIsoAt(const Vec2& pos)
{
return Vec2(_mapTileSize.width /2 * (_layerSize.width + pos.x - pos.y - 1),
_mapTileSize.height /2 * ((_layerSize.height * 2 - pos.x - pos.y) - 2));
}
Vec2 TMXLayer::getPositionForHexAt(const Vec2& pos)
{
Vec2 xy;
Vec2 offset = _tileSet->_tileOffset;
int odd_even = (_staggerIndex == TMXStaggerIndex_Odd) ? 1 : -1;
switch (_staggerAxis)
{
case TMXStaggerAxis_Y:
{
float diffX = 0;
if ((int)pos.y % 2 == 1)
{
diffX = _mapTileSize.width/2 * odd_even;
}
xy = Vec2(pos.x * _mapTileSize.width+diffX+offset.x,
(_layerSize.height - pos.y - 1) * (_mapTileSize.height-(_mapTileSize.height-_hexSideLength)/2)-offset.y);
break;
}
case TMXStaggerAxis_X:
{
float diffY = 0;
if ((int)pos.x % 2 == 1)
{
diffY = _mapTileSize.height/2 * -odd_even;
}
xy = Vec2(pos.x * (_mapTileSize.width-(_mapTileSize.width-_hexSideLength)/2)+offset.x,
(_layerSize.height - pos.y - 1) * _mapTileSize.height + diffY-offset.y);
break;
}
}
return xy;
}
Vec2 TMXLayer::getPositionForStaggeredAt(const Vec2 &pos)
{
float diffX = 0;
if ((int)pos.y % 2 == 1)
{
diffX = _mapTileSize.width/2;
}
return Vec2(pos.x * _mapTileSize.width + diffX,
(_layerSize.height - pos.y - 1) * _mapTileSize.height/2);
}
int TMXLayer::getVertexZForPos(const Vec2& pos)
{
int ret = 0;
int maxVal = 0;
if (_useAutomaticVertexZ)
{
switch (_layerOrientation)
{
case TMXOrientationIso:
maxVal = static_cast<int>(_layerSize.width + _layerSize.height);
ret = static_cast<int>(-(maxVal - (pos.x + pos.y)));
break;
case TMXOrientationOrtho:
ret = static_cast<int>(-(_layerSize.height-pos.y));
break;
case TMXOrientationStaggered:
ret = static_cast<int>(-(_layerSize.height-pos.y));
break;
case TMXOrientationHex:
ret = static_cast<int>(-(_layerSize.height-pos.y));
break;
default:
CCASSERT(0, "TMX invalid value");
break;
}
}
else
{
ret = _vertexZvalue;
}
return ret;
}
std::string TMXLayer::getDescription() const
{
return StringUtils::format("<TMXLayer | tag = %d, size = %d,%d>", _tag, (int)_mapTileSize.width, (int)_mapTileSize.height);
}
NS_CC_END

View File

@ -1,346 +0,0 @@
/****************************************************************************
Copyright (c) 2008-2010 Ricardo Quesada
Copyright (c) 2010-2012 cocos2d-x.org
Copyright (c) 2011 Zynga Inc.
Copyright (c) 2013-2016 Chukong Technologies Inc.
Copyright (c) 2017-2018 Xiamen Yaji Software Co., Ltd.
http://www.cocos2d-x.org
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
****************************************************************************/
#ifndef __CCTMX_LAYER_H__
#define __CCTMX_LAYER_H__
#include "2d/CCSpriteBatchNode.h"
#include "2d/CCTMXXMLParser.h"
#include "base/ccCArray.h"
NS_CC_BEGIN
class TMXMapInfo;
class TMXLayerInfo;
class TMXTilesetInfo;
struct _ccCArray;
/**
* @addtogroup _2d
* @{
*/
/** @brief TMXLayer represents the TMX layer.
* It is a subclass of SpriteBatchNode. By default the tiles are rendered using a TextureAtlas.
* If you modify a tile on runtime, then, that tile will become a Sprite, otherwise no Sprite objects are created.
* The benefits of using Sprite objects as tiles are:
* - tiles (Sprite) can be rotated/scaled/moved with a nice API.
* If the layer contains a property named "cc_vertexz" with an integer (in can be positive or negative),
* then all the tiles belonging to the layer will use that value as their OpenGL vertex Z for depth.
* On the other hand, if the "cc_vertexz" property has the "automatic" value, then the tiles will use an automatic vertex Z value.
* Also before drawing the tiles, GL_ALPHA_TEST will be enabled, and disabled after drawing them. The used alpha func will be:
* glAlphaFunc( GL_GREATER, value ).
* "value" by default is 0, but you can change it from Tiled by adding the "cc_alpha_func" property to the layer.
* The value 0 should work for most cases, but if you have tiles that are semi-transparent, then you might want to use a different
* value, like 0.5.
* For further information, please see the programming guide:
* http://www.cocos2d-iphone.org/wiki/doku.php/prog_guide:tiled_maps
* @since v0.8.1
* Tiles can have tile flags for additional properties. At the moment only flip horizontal and flip vertical are used. These bit flags are defined in TMXXMLParser.h.
* @since 1.1
*/
class CC_DLL TMXLayer : public SpriteBatchNode
{
public:
/** Creates a TMXLayer with an tileset info, a layer info and a map info.
*
* @param tilesetInfo An tileset info.
* @param layerInfo A layer info.
* @param mapInfo A map info.
* @return An autorelease object.
*/
static TMXLayer * create(TMXTilesetInfo *tilesetInfo, TMXLayerInfo *layerInfo, TMXMapInfo *mapInfo);
/**
* @js ctor
*/
TMXLayer();
/**
* @js NA
* @lua NA
*/
virtual ~TMXLayer();
/** Initializes a TMXLayer with a tileset info, a layer info and a map info.
*
* @param tilesetInfo An tileset info.
* @param layerInfo A layer info.
* @param mapInfo A map info.
* @return If initializes successfully, it will return true.
*/
bool initWithTilesetInfo(TMXTilesetInfo *tilesetInfo, TMXLayerInfo *layerInfo, TMXMapInfo *mapInfo);
/** Dealloc the map that contains the tile position from memory.
* Unless you want to know at runtime the tiles positions, you can safely call this method.
* If you are going to call layer->tileGIDAt() then, don't release the map.
*/
void releaseMap();
/** Returns the tile (Sprite) at a given a tile coordinate.
* The returned Sprite will be already added to the TMXLayer. Don't add it again.
* The Sprite can be treated like any other Sprite: rotated, scaled, translated, opacity, color, etc.
* You can remove either by calling:
* - layer->removeChild(sprite, cleanup);
* - or layer->removeTileAt(Vec2(x,y));
*
* @param tileCoordinate A tile coordinate.
* @return Returns the tile (Sprite) at a given a tile coordinate.
*/
Sprite* getTileAt(const Vec2& tileCoordinate);
/** Returns the tile gid at a given tile coordinate. It also returns the tile flags.
* This method requires the tile map has not been previously released (eg. don't call [layer releaseMap]).
*
* @param tileCoordinate The tile coordinate.
* @param flags Tile flags.
* @return Returns the tile gid at a given tile coordinate. It also returns the tile flags.
*/
uint32_t getTileGIDAt(const Vec2& tileCoordinate, TMXTileFlags* flags = nullptr);
/** 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.
* If a tile is already placed at that position, then it will be removed.
*
* @param gid The tile gid.
* @param tileCoordinate The tile coordinate.
*/
void setTileGID(uint32_t gid, const Vec2& 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.
* If a tile is already placed at that position, then it will be removed.
* Use withFlags if the tile flags need to be changed as well.
*
* @param gid The tile gid.
* @param tileCoordinate The tile coordinate.
* @param flags The tile flags.
*/
void setTileGID(uint32_t gid, const Vec2& tileCoordinate, TMXTileFlags flags);
/** Removes a tile at given tile coordinate.
*
* @param tileCoordinate The tile coordinate.
*/
void removeTileAt(const Vec2& tileCoordinate);
/** Returns the position in points of a given tile coordinate.
*
* @param tileCoordinate The tile coordinate.
* @return The position in points of a given tile coordinate.
*/
Vec2 getPositionAt(const Vec2& tileCoordinate);
/** Return the value for the specific property name.
*
* @param propertyName The specific property name.
* @return Return the value for the specific property name.
*/
Value getProperty(const std::string& propertyName) const;
/** Creates the tiles. */
void setupTiles();
/** Get the layer name.
*
* @return The layer name.
*/
const std::string& getLayerName() { return _layerName; }
/** Set the layer name.
*
* @param layerName The layer name.
*/
void setLayerName(const std::string& layerName) { _layerName = layerName; }
/** Size of the layer in tiles.
*
* @return Size of the layer in tiles.
*/
const Size& getLayerSize() const { return _layerSize; }
/** Set size of the layer in tiles.
*
* @param size Size of the layer in tiles.
*/
void setLayerSize(const Size& size) { _layerSize = size; }
/** Size of the map's tile (could be different from the tile's size).
*
* @return The size of the map's tile.
*/
const Size& getMapTileSize() const { return _mapTileSize; }
/** Set the size of the map's tile.
*
* @param size The size of the map's tile.
*/
void setMapTileSize(const Size& size) { _mapTileSize = size; }
/** Pointer to the map of tiles.
* @js NA
* @lua NA
* @return Pointer to the map of tiles.
*/
uint32_t* getTiles() const { return _tiles; };
/** Set a pointer to the map of tiles.
*
* @param tiles A pointer to the map of tiles.
*/
void setTiles(uint32_t* tiles) { _tiles = tiles; };
/** Tileset information for the layer.
*
* @return Tileset information for the layer.
*/
TMXTilesetInfo* getTileSet() const { return _tileSet; }
/** Set tileset information for the layer.
*
* @param info The tileset information for the layer.
* @js NA
*/
void setTileSet(TMXTilesetInfo* info) {
CC_SAFE_RETAIN(info);
CC_SAFE_RELEASE(_tileSet);
_tileSet = info;
}
/** Layer orientation, which is the same as the map orientation.
*
* @return Layer orientation, which is the same as the map orientation.
*/
int getLayerOrientation() const { return _layerOrientation; }
/** Set layer orientation, which is the same as the map orientation.
*
* @param orientation Layer orientation,which is the same as the map orientation.
*/
void setLayerOrientation(int orientation) { _layerOrientation = orientation; }
/** Properties from the layer. They can be added using Tiled.
*
* @return Properties from the layer. They can be added using Tiled.
*/
const ValueMap& getProperties() const { return _properties; }
/** Properties from the layer. They can be added using Tiled.
*
* @return Properties from the layer. They can be added using Tiled.
*/
ValueMap& getProperties() { return _properties; }
/** Set an Properties from to layer.
*
* @param properties It is used to set the layer Properties.
*/
void setProperties(const ValueMap& properties) {
_properties = properties;
}
//
// Override
//
/** TMXLayer doesn't support adding a Sprite manually.
@warning addChild(z, tag); is not supported on TMXLayer. Instead of setTileGID.
*/
using SpriteBatchNode::addChild;
virtual void addChild(Node * child, int zOrder, int tag) override;
// super method
void removeChild(Node* child, bool cleanup) override;
/**
* @js NA
*/
virtual std::string getDescription() const override;
protected:
Vec2 getPositionForIsoAt(const Vec2& pos);
Vec2 getPositionForOrthoAt(const Vec2& pos);
Vec2 getPositionForHexAt(const Vec2& pos);
Vec2 getPositionForStaggeredAt(const Vec2& pos);
Vec2 calculateLayerOffset(const Vec2& offset);
/* optimization methods */
Sprite* appendTileForGID(uint32_t gid, const Vec2& pos);
Sprite* insertTileForGID(uint32_t gid, const Vec2& pos);
Sprite* updateTileForGID(uint32_t gid, const Vec2& pos);
intptr_t getZForPos(const Vec2& pos) const;
/* The layer recognizes some special properties, like cc_vertexz */
void parseInternalProperties();
void setupTileSprite(Sprite* sprite, const Vec2& pos, uint32_t gid);
Sprite* reusedTileWithRect(const Rect& rect);
int getVertexZForPos(const Vec2& pos);
// index
ssize_t atlasIndexForExistantZ(int z);
ssize_t atlasIndexForNewZ(int z);
//! name of the layer
std::string _layerName;
//! TMX Layer supports opacity
unsigned char _opacity;
//! Only used when vertexZ is used
int _vertexZvalue;
bool _useAutomaticVertexZ;
//! used for optimization
Sprite *_reusedTile;
ccCArray *_atlasIndexArray;
// used for retina display
float _contentScaleFactor;
/** size of the layer in tiles */
Size _layerSize;
/** size of the map's tile (could be different from the tile's size) */
Size _mapTileSize;
/** pointer to the map of tiles */
uint32_t* _tiles;
/** Tileset information for the layer */
TMXTilesetInfo* _tileSet;
/** Layer orientation, which is the same as the map orientation */
int _layerOrientation;
/** Stagger Axis */
int _staggerAxis;
/** Stagger Index */
int _staggerIndex;
/** Hex side length*/
int _hexSideLength;
/** properties from the layer. They can be added using Tiled */
ValueMap _properties;
};
// end of tilemap_parallax_nodes group
/** @} */
NS_CC_END
#endif //__CCTMX_LAYER_H__

View File

@ -1,276 +0,0 @@
/****************************************************************************
Copyright (c) 2009-2010 Ricardo Quesada
Copyright (c) 2010-2012 cocos2d-x.org
Copyright (c) 2011 Zynga Inc.
Copyright (c) 2013-2016 Chukong Technologies Inc.
Copyright (c) 2017-2018 Xiamen Yaji Software Co., Ltd.
http://www.cocos2d-x.org
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
****************************************************************************/
#include "2d/CCTMXTiledMap.h"
#include "2d/CCTMXXMLParser.h"
#include "2d/CCTMXLayer.h"
#include "2d/CCSprite.h"
#include "base/ccUTF8.h"
NS_CC_BEGIN
// implementation TMXTiledMap
TMXTiledMap * TMXTiledMap::create(const std::string& tmxFile)
{
TMXTiledMap *ret = new (std::nothrow) TMXTiledMap();
if (ret->initWithTMXFile(tmxFile))
{
ret->autorelease();
return ret;
}
CC_SAFE_DELETE(ret);
return nullptr;
}
TMXTiledMap* TMXTiledMap::createWithXML(const std::string& tmxString, const std::string& resourcePath)
{
TMXTiledMap *ret = new (std::nothrow) TMXTiledMap();
if (ret->initWithXML(tmxString, resourcePath))
{
ret->autorelease();
return ret;
}
CC_SAFE_DELETE(ret);
return nullptr;
}
bool TMXTiledMap::initWithTMXFile(const std::string& tmxFile)
{
CCASSERT(tmxFile.size()>0, "TMXTiledMap: tmx file should not be empty");
_tmxFile = tmxFile;
setContentSize(Size::ZERO);
TMXMapInfo *mapInfo = TMXMapInfo::create(tmxFile);
if (! mapInfo)
{
return false;
}
CCASSERT( !mapInfo->getTilesets().empty(), "TMXTiledMap: Map not found. Please check the filename.");
buildWithMapInfo(mapInfo);
return true;
}
bool TMXTiledMap::initWithXML(const std::string& tmxString, const std::string& resourcePath)
{
_tmxFile = tmxString;
setContentSize(Size::ZERO);
TMXMapInfo *mapInfo = TMXMapInfo::createWithXML(tmxString, resourcePath);
CCASSERT( !mapInfo->getTilesets().empty(), "TMXTiledMap: Map not found. Please check the filename.");
buildWithMapInfo(mapInfo);
return true;
}
TMXTiledMap::TMXTiledMap()
:_mapSize(Size::ZERO)
,_tileSize(Size::ZERO)
,_tmxFile("")
, _tmxLayerNum(0)
{
}
TMXTiledMap::~TMXTiledMap()
{
}
// private
TMXLayer * TMXTiledMap::parseLayer(TMXLayerInfo *layerInfo, TMXMapInfo *mapInfo)
{
TMXTilesetInfo *tileset = tilesetForLayer(layerInfo, mapInfo);
if (tileset == nullptr)
return nullptr;
TMXLayer *layer = TMXLayer::create(tileset, layerInfo, mapInfo);
if (nullptr != layer)
{
// tell the layerinfo to release the ownership of the tiles map.
layerInfo->_ownTiles = false;
layer->setupTiles();
}
return layer;
}
TMXTilesetInfo * TMXTiledMap::tilesetForLayer(TMXLayerInfo *layerInfo, TMXMapInfo *mapInfo)
{
auto height = static_cast<uint32_t>(layerInfo->_layerSize.height);
auto width = static_cast<uint32_t>(layerInfo->_layerSize.width);
auto& tilesets = mapInfo->getTilesets();
for (auto iter = tilesets.crbegin(), end = tilesets.crend(); iter != end; ++iter)
{
TMXTilesetInfo* tileset = *iter;
if (tileset)
{
for (uint32_t y = 0; y < height; y++)
{
for (uint32_t x = 0; x < width; x++)
{
auto pos = x + width * y;
auto gid = layerInfo->_tiles[ pos ];
// FIXME:: gid == 0 --> empty tile
if (gid != 0)
{
// Optimization: quick return
// if the layer is invalid (more than 1 tileset per layer)
// an CCAssert will be thrown later
if (tileset->_firstGid < 0 ||
(gid & kTMXFlippedMask) >= static_cast<uint32_t>(tileset->_firstGid))
return tileset;
}
}
}
}
}
// If all the tiles are 0, return empty tileset
CCLOG("cocos2d: Warning: TMX Layer '%s' has no tiles", layerInfo->_name.c_str());
return nullptr;
}
void TMXTiledMap::buildWithMapInfo(TMXMapInfo* mapInfo)
{
_mapSize = mapInfo->getMapSize();
_tileSize = mapInfo->getTileSize();
_mapOrientation = mapInfo->getOrientation();
_objectGroups = mapInfo->getObjectGroups();
_properties = mapInfo->getProperties();
_tileProperties = mapInfo->getTileProperties();
int idx = 0;
auto& layers = mapInfo->getLayers();
for (const auto &layerInfo : layers) {
if (layerInfo->_visible) {
TMXLayer *child = parseLayer(layerInfo, mapInfo);
if (child == nullptr) {
idx++;
continue;
}
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++;
}
}
_tmxLayerNum = idx;
}
// public
TMXLayer * TMXTiledMap::getLayer(const std::string& layerName) const
{
CCASSERT(!layerName.empty(), "Invalid layer name!");
for (auto& child : _children)
{
TMXLayer* layer = dynamic_cast<TMXLayer*>(child);
if(layer)
{
if(layerName.compare( layer->getLayerName()) == 0)
{
return layer;
}
}
}
// layer not found
return nullptr;
}
TMXObjectGroup * TMXTiledMap::getObjectGroup(const std::string& groupName) const
{
CCASSERT(!groupName.empty(), "Invalid group name!");
for (const auto objectGroup : _objectGroups)
{
if (objectGroup && objectGroup->getGroupName() == groupName)
{
return objectGroup;
}
}
// objectGroup not found
return nullptr;
}
Value TMXTiledMap::getProperty(const std::string& propertyName) const
{
if (_properties.find(propertyName) != _properties.end())
return _properties.at(propertyName);
return Value();
}
Value TMXTiledMap::getPropertiesForGID(int GID) const
{
if (_tileProperties.find(GID) != _tileProperties.end())
return _tileProperties.at(GID);
return Value();
}
bool TMXTiledMap::getPropertiesForGID(int GID, Value** value)
{
if (_tileProperties.find(GID) != _tileProperties.end()) {
*value = &_tileProperties.at(GID);
return true;
} else {
return false;
}
}
std::string TMXTiledMap::getDescription() const
{
return StringUtils::format("<TMXTiledMap | Tag = %d, Layers = %d", _tag, static_cast<int>(_children.size()));
}
int TMXTiledMap::getLayerNum()
{
return _tmxLayerNum;
}
NS_CC_END

View File

@ -1,316 +0,0 @@
/****************************************************************************
Copyright (c) 2009-2010 Ricardo Quesada
Copyright (c) 2010-2012 cocos2d-x.org
Copyright (c) 2011 Zynga Inc.
Copyright (c) 2013-2016 Chukong Technologies Inc.
Copyright (c) 2017-2018 Xiamen Yaji Software Co., Ltd.
http://www.cocos2d-x.org
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
****************************************************************************/
#ifndef __CCTMX_TILE_MAP_H__
#define __CCTMX_TILE_MAP_H__
#include "2d/CCNode.h"
#include "2d/CCTMXObjectGroup.h"
#include "base/CCValue.h"
NS_CC_BEGIN
class TMXLayer;
class TMXLayerInfo;
class TMXTilesetInfo;
class TMXMapInfo;
/**
* @addtogroup _2d
* @{
*/
/** Possible orientations of the TMX map. */
enum
{
/** Orthogonal orientation. */
TMXOrientationOrtho,
/** Hexagonal orientation. */
TMXOrientationHex,
/** Isometric orientation. */
TMXOrientationIso,
/** Isometric staggered orientation. */
TMXOrientationStaggered,
};
/** Possible stagger axis of the TMX map. */
enum
{
/** Stagger Axis x. */
TMXStaggerAxis_X,
/** Stagger Axis y. */
TMXStaggerAxis_Y,
};
/** Possible stagger index of the TMX map. */
enum
{
/** Stagger Index: Odd */
TMXStaggerIndex_Odd,
/** Stagger Index: Even */
TMXStaggerIndex_Even,
};
/** @brief TMXTiledMap knows how to parse and render a TMX map.
* It adds support for the TMX tiled map format used by http://www.mapeditor.org
* It supports isometric, hexagonal and orthogonal tiles.
* It also supports object groups, objects, and properties.
* Features:
* - Each tile will be treated as an Sprite.
* - The sprites are created on demand. They will be created only when you call "layer->tileAt(position)".
* - Each tile can be rotated / moved / scaled / tinted / "opaqued", since each tile is a Sprite.
* - Tiles can be added/removed in runtime.
* - The z-order of the tiles can be modified in runtime.
* - Each tile has an anchorPoint of (0,0).
* - The anchorPoint of the TMXTileMap is (0,0).
* - The TMX layers will be added as a child.
* - The TMX layers will be aliased by default.
* - The tileset image will be loaded using the TextureCache.
* - Each tile will have a unique tag.
* - Each tile will have a unique z value. top-left: z=1, bottom-right: z=max z.
* - Each object group will be treated as an MutableArray.
* - Object class which will contain all the properties in a dictionary.
* - Properties can be assigned to the Map, Layer, Object Group, and Object.
* Limitations:
* - It only supports one tileset per layer.
* - Embedded images are not supported.
* - It only supports the XML format (the JSON format is not supported).
* Technical description:
* Each layer is created using an TMXLayer (subclass of SpriteBatchNode). If you have 5 layers, then 5 TMXLayer will be created,
* unless the layer visibility is off. In that case, the layer won't be created at all.
* You can obtain the layers (TMXLayer objects) at runtime by:
* - map->getChildByTag(tag_number); // 0=1st layer, 1=2nd layer, 2=3rd layer, etc...
* - map->getLayer(name_of_the_layer);
* Each object group is created using a TMXObjectGroup which is a subclass of MutableArray.
* You can obtain the object groups at runtime by:
* - map->getObjectGroup(name_of_the_object_group);
* Each object is a TMXObject.
* Each property is stored as a key-value pair in an MutableDictionary.
* You can obtain the properties at runtime by:
* map->getProperty(name_of_the_property);
* layer->getProperty(name_of_the_property);
* objectGroup->getProperty(name_of_the_property);
* object->getProperty(name_of_the_property);
* @since v0.8.1
*/
class CC_DLL TMXTiledMap : public Node
{
public:
/** Creates a TMX Tiled Map with a TMX file.
*
* @param tmxFile A TMX file.
* @return An autorelease object.
*/
static TMXTiledMap* create(const std::string& tmxFile);
/** Initializes a TMX Tiled Map with a TMX formatted XML string and a path to TMX resources.
*
* @param tmxString A TMX formatted XML string.
* @param resourcePath The path to TMX resources.
* @return An autorelease object.
* @js NA
*/
static TMXTiledMap* createWithXML(const std::string& tmxString, const std::string& resourcePath);
/** Return the TMXLayer for the specific layer.
*
* @param layerName A specific layer.
* @return The TMXLayer for the specific layer.
*/
TMXLayer* getLayer(const std::string& layerName) const;
/** Return the TMXObjectGroup for the specific group.
*
* @param groupName The group Name.
* @return A Type of TMXObjectGroup.
*/
TMXObjectGroup* getObjectGroup(const std::string& groupName) const;
/** Return the value for the specific property name.
*
* @param propertyName The specific property name.
* @return Return the value for the specific property name.
*/
Value getProperty(const std::string& propertyName) const;
/** Return properties dictionary for tile GID.
*
* @param GID The tile GID.
* @return Return properties dictionary for tile GID.
*/
Value getPropertiesForGID(int GID) const;
/** Assigns properties to argument value, returns true if it did found properties
* for that GID and did assigned a value, else it returns false.
*
* @param GID The tile GID.
* @param value Argument value.
* @return Return true if it did found properties for that GID and did assigned a value, else it returns false.
*/
bool getPropertiesForGID(int GID, Value** value);
/** The map's size property measured in tiles.
*
* @return The map's size property measured in tiles.
*/
const Size& getMapSize() const { return _mapSize; }
/** Set the map's size property measured in tiles.
*
* @param mapSize The map's size property measured in tiles.
*/
void setMapSize(const Size& mapSize) { _mapSize = mapSize; }
/** The tiles's size property measured in pixels.
*
* @return The tiles's size property measured in pixels.
*/
const Size& getTileSize() const { return _tileSize; }
/** Set the tiles's size property measured in pixels.
*
* @param tileSize The tiles's size property measured in pixels.
*/
void setTileSize(const Size& tileSize) { _tileSize = tileSize; }
/** Map orientation.
*
* @return Map orientation.
*/
int getMapOrientation() const { return _mapOrientation; }
/** Set map orientation.
*
* @param mapOrientation The map orientation.
*/
void setMapOrientation(int mapOrientation) { _mapOrientation = mapOrientation; }
/** Get the Object groups.
*
* @return The object groups.
*/
const Vector<TMXObjectGroup*>& getObjectGroups() const { return _objectGroups; }
Vector<TMXObjectGroup*>& getObjectGroups() { return _objectGroups; }
/** Set the object groups.
*
* @param groups The object groups.
*/
void setObjectGroups(const Vector<TMXObjectGroup*>& groups) {
_objectGroups = groups;
}
/** Properties.
*
* @return Properties.
*/
ValueMap& getProperties() { return _properties; }
/** Set the properties.
*
* @param properties A Type of ValueMap to set the properties.
*/
void setProperties(const ValueMap& properties) {
_properties = properties;
}
/** Get the description.
* @js NA
*/
virtual std::string getDescription() const override;
int getLayerNum();
const std::string& getResourceFile() const { return _tmxFile; }
CC_CONSTRUCTOR_ACCESS:
/**
* @js ctor
*/
TMXTiledMap();
/**
* @js NA
* @lua NA
*/
virtual ~TMXTiledMap();
/** initializes a TMX Tiled Map with a TMX file */
bool initWithTMXFile(const std::string& tmxFile);
/** initializes a TMX Tiled Map with a TMX formatted XML string and a path to TMX resources */
bool initWithXML(const std::string& tmxString, const std::string& resourcePath);
protected:
TMXLayer * parseLayer(TMXLayerInfo *layerInfo, TMXMapInfo *mapInfo);
TMXTilesetInfo * tilesetForLayer(TMXLayerInfo *layerInfo, TMXMapInfo *mapInfo);
void buildWithMapInfo(TMXMapInfo* mapInfo);
/** the map's size property measured in tiles */
Size _mapSize;
/** the tiles's size property measured in pixels */
Size _tileSize;
/** map orientation */
int _mapOrientation;
/** object groups */
Vector<TMXObjectGroup*> _objectGroups;
/** properties */
ValueMap _properties;
//! tile properties
ValueMapIntKey _tileProperties;
std::string _tmxFile;
int _tmxLayerNum;
static const int TMXLayerTag = 32768;
private:
CC_DISALLOW_COPY_AND_ASSIGN(TMXTiledMap);
};
// end of tilemap_parallax_nodes group
/// @}
NS_CC_END
#endif //__CCTMX_TILE_MAP_H__

View File

@ -30,7 +30,7 @@ THE SOFTWARE.
#include "2d/CCTMXXMLParser.h"
#include <unordered_map>
#include <sstream>
#include "2d/CCTMXTiledMap.h"
// #include "2d/CCTMXTiledMap.h"
#include "base/ZipUtils.h"
#include "base/base64.h"
#include "base/CCDirector.h"
@ -665,6 +665,19 @@ void TMXMapInfo::startElement(void* /*ctx*/, const char *name, const char **atts
dict["polylinePoints"] = Value(pointsArray);
}
}
else if (elementName == "animation")
{
TMXTilesetInfo* info = tmxMapInfo->getTilesets().back();
info->_animationInfo.insert(tmxMapInfo->getParentGID(), TMXTileAnimInfo::create(tmxMapInfo->getParentGID()));
tmxMapInfo->setParentElement(TMXPropertyAnimation);
}
else if (elementName == "frame")
{
TMXTilesetInfo* info = tmxMapInfo->getTilesets().back();
auto animInfo = info->_animationInfo.at(tmxMapInfo->getParentGID());
// calculate gid of frame
animInfo->_frames.emplace_back(TMXTileAnimFrame(info->_firstGid + attributeDict["tileid"].asInt(), attributeDict["duration"].asFloat()));
}
}
void TMXMapInfo::endElement(void* /*ctx*/, const char *name)
@ -785,6 +798,10 @@ void TMXMapInfo::endElement(void* /*ctx*/, const char *name)
{
_recordFirstGID = true;
}
else if (elementName == "animation")
{
tmxMapInfo->setParentElement(TMXPropertyNone);
}
}
void TMXMapInfo::textHandler(void* /*ctx*/, const char *ch, size_t len)
@ -800,4 +817,28 @@ void TMXMapInfo::textHandler(void* /*ctx*/, const char *ch, size_t len)
}
}
TMXTileAnimFrame::TMXTileAnimFrame(uint32_t tileID, float duration)
: _tileID(tileID)
, _duration(duration)
{
}
TMXTileAnimInfo::TMXTileAnimInfo(uint32_t tileID)
: _tileID(tileID)
{
}
TMXTileAnimInfo* TMXTileAnimInfo::create(uint32_t tileID)
{
TMXTileAnimInfo* ret = new (std::nothrow) TMXTileAnimInfo(tileID);
if (ret)
{
ret->autorelease();
return ret;
}
CC_SAFE_DELETE(ret);
return nullptr;
}
NS_CC_END

View File

@ -35,6 +35,7 @@ THE SOFTWARE.
#include "math/CCGeometry.h"
#include "platform/CCSAXParser.h"
#include "base/CCVector.h"
#include "base/CCMap.h"
#include "base/CCValue.h"
#include "2d/CCTMXObjectGroup.h" // needed for Vector<TMXObjectGroup*> for binding
@ -72,7 +73,8 @@ enum {
TMXPropertyLayer,
TMXPropertyObjectGroup,
TMXPropertyObject,
TMXPropertyTile
TMXPropertyTile,
TMXPropertyAnimation
};
typedef enum TMXTileFlags_ {
@ -83,6 +85,77 @@ typedef enum TMXTileFlags_ {
kTMXFlippedMask = ~(kTMXFlipedAll)
} TMXTileFlags;
/**
* @addtogroup _2d
* @{
*/
/** Possible orientations of the TMX map. */
enum
{
/** Orthogonal orientation. */
TMXOrientationOrtho,
/** Hexagonal orientation. */
TMXOrientationHex,
/** Isometric orientation. */
TMXOrientationIso,
/** Isometric staggered orientation. */
TMXOrientationStaggered,
};
/** Possible stagger axis of the TMX map. */
enum
{
/** Stagger Axis x. */
TMXStaggerAxis_X,
/** Stagger Axis y. */
TMXStaggerAxis_Y,
};
/** Possible stagger index of the TMX map. */
enum
{
/** Stagger Index: Odd */
TMXStaggerIndex_Odd,
/** Stagger Index: Even */
TMXStaggerIndex_Even,
};
/** @brief TMXTileAnimFrame contains the information about the frame of a animated tile like:
- Frame gid
- duration of this frame
This information is obtained from the TMX file.
*/
struct CC_DLL TMXTileAnimFrame
{
TMXTileAnimFrame(uint32_t tileID, float duration);
/** gid of the frame */
uint32_t _tileID = 0;
/** duration of the frame */
float _duration = 0.0f;
};
/** @brief TMXTileAnimInfo contains the information about the animated tile like:
- Animated Tile gid
- frames the animated tile contains
This information is obtained from the TMX file.
*/
struct CC_DLL TMXTileAnimInfo : public Ref
{
static TMXTileAnimInfo* create(uint32_t tileID);
explicit TMXTileAnimInfo(uint32_t tileID);
uint32_t _tileID = 0;
std::vector<TMXTileAnimFrame> _frames;
};
// Bits on the far end of the 32-bit global tile ID (GID's) are used for tile flags
/** @brief TMXLayerInfo contains the information about the layers like:
@ -143,7 +216,8 @@ public:
//! size in pixels of the image
Size _imageSize;
std::string _originSourceImage;
//! map from gid of animated tile to its animation info
Map<uint32_t, TMXTileAnimInfo*> _animationInfo;
public:
/**
* @js ctor

View File

@ -4,7 +4,7 @@ set(COCOS_2D_HEADER
2d/CCActionTween.h
2d/CCGrid.h
2d/CCSpriteFrameCache.h
2d/CCTMXTiledMap.h
# 2d/CCTMXTiledMap.h
2d/CCLayer.h
2d/CCActionCamera.h
2d/CCParticleExamples.h
@ -63,7 +63,7 @@ set(COCOS_2D_HEADER
2d/CCMotionStreak.h
2d/CCMenu.h
2d/CCDrawNode.h
2d/CCTMXLayer.h
#2d/CCTMXLayer.h
2d/CCCamera.h
2d/CCParallaxNode.h
)
@ -128,9 +128,9 @@ set(COCOS_2D_SRC
2d/CCAutoPolygon.cpp
2d/CCTextFieldTTF.cpp
2d/CCTileMapAtlas.cpp
2d/CCTMXLayer.cpp
# 2d/CCTMXLayer.cpp
2d/CCTMXObjectGroup.cpp
2d/CCTMXTiledMap.cpp
# 2d/CCTMXTiledMap.cpp
2d/CCTMXXMLParser.cpp
2d/CCTransition.cpp
2d/CCTransitionPageTurn.cpp

View File

@ -238,9 +238,7 @@ THE SOFTWARE.
// tilemap_parallax_nodes
#include "2d/CCParallaxNode.h"
#include "2d/CCTMXLayer.h"
#include "2d/CCTMXObjectGroup.h"
#include "2d/CCTMXTiledMap.h"
#include "2d/CCTMXXMLParser.h"
#include "2d/CCTileMapAtlas.h"
#include "2d/CCFastTMXLayer.h"

View File

@ -58,9 +58,9 @@
#include "2d/CCParticleSystemQuad.h"
#include "2d/CCProgressTimer.h"
#include "2d/CCSpriteFrameCache.h"
#include "2d/CCTMXLayer.h"
#include "2d/CCFastTMXLayer.h"
#include "2d/CCTMXObjectGroup.h"
#include "2d/CCTMXTiledMap.h"
#include "2d/CCFastTMXTiledMap.h"
#include "2d/CCTMXXMLParser.h"
#include "2d/CCTextFieldTTF.h"
#include "2d/CCTileMapAtlas.h"
@ -811,8 +811,8 @@ CC_DEPRECATED_ATTRIBUTE typedef TMXObjectGroup CCTMXObjectGroup;
CC_DEPRECATED_ATTRIBUTE typedef TMXLayerInfo CCTMXLayerInfo;
CC_DEPRECATED_ATTRIBUTE typedef TMXTilesetInfo CCTMXTilesetInfo;
CC_DEPRECATED_ATTRIBUTE typedef TMXMapInfo CCTMXMapInfo;
CC_DEPRECATED_ATTRIBUTE typedef TMXLayer CCTMXLayer;
CC_DEPRECATED_ATTRIBUTE typedef TMXTiledMap CCTMXTiledMap;
//CC_DEPRECATED_ATTRIBUTE typedef TMXLayer CCTMXLayer;
//CC_DEPRECATED_ATTRIBUTE typedef TMXTiledMap CCTMXTiledMap;
CC_DEPRECATED_ATTRIBUTE typedef TileMapAtlas CCTileMapAtlas;
CC_DEPRECATED_ATTRIBUTE typedef Timer CCTimer;
CC_DEPRECATED_ATTRIBUTE typedef Scheduler CCScheduler;

View File

@ -100719,7 +100719,7 @@ int lua_cocos2dx_TMXLayer_releaseMap(lua_State* tolua_S)
tolua_error(tolua_S,"invalid arguments in function 'lua_cocos2dx_TMXLayer_releaseMap'", nullptr);
return 0;
}
cobj->releaseMap();
// cobj->release();
lua_settop(tolua_S, 1);
return 1;
}
@ -102274,7 +102274,7 @@ int lua_cocos2dx_TMXTiledMap_getProperties(lua_State* tolua_S)
tolua_error(tolua_S,"invalid arguments in function 'lua_cocos2dx_TMXTiledMap_getProperties'", nullptr);
return 0;
}
cocos2d::ValueMap& ret = cobj->getProperties();
auto& ret = cobj->getProperties();
ccvaluemap_to_luaval(tolua_S, ret);
return 1;
}

View File

@ -46,8 +46,6 @@
#include "2d/CCParticleSystem.h"
#include "2d/CCScene.h"
#include "2d/CCSpriteBatchNode.h"
#include "2d/CCTMXLayer.h"
#include "2d/CCTMXTiledMap.h"
#include "2d/CCFastTMXLayer.h"
#include "2d/CCFastTMXTiledMap.h"
#include "2d/CCRenderTexture.h"

View File

@ -32,7 +32,7 @@
#include "ui/CocosGUI.h"
#include "2d/CCSpriteFrameCache.h"
#include "2d/CCParticleSystemQuad.h"
#include "2d/CCTMXTiledMap.h"
#include "2d/CCFastTMXTiledMap.h"
#include "platform/CCFileUtils.h"
#include "cocostudio/ActionTimeline/CCActionTimelineCache.h"

View File

@ -26,7 +26,7 @@ THE SOFTWARE.
#include "cocostudio/CocoStudio.h"
#include "platform/CCFileUtils.h"
#include "2d/CCTMXTiledMap.h"
#include "2d/CCFastTMXTiledMap.h"
#include "2d/CCParticleSystemQuad.h"
#include "2d/CCSpriteFrameCache.h"

View File

@ -26,7 +26,7 @@
#include "2d/CCLabel.h"
#include "2d/CCTMXXMLParser.h"
#include "2d/CCTMXTiledMap.h"
#include "2d/CCFastTMXTiledMap.h"
#include "platform/CCFileUtils.h"
#include "base/ccUTF8.h"
@ -134,7 +134,7 @@ namespace cocostudio
Node* GameMapReader::createNodeWithFlatBuffers(const flatbuffers::Table *gameMapOptions)
{
TMXTiledMap* tmx = nullptr;
FastTMXTiledMap* tmx = nullptr;
auto options = (GameMapOptions*)gameMapOptions;
auto fileNameData = options->fileNameData();
@ -235,7 +235,7 @@ namespace cocostudio
}
/**/
tmx = TMXTiledMap::create(path);
tmx = FastTMXTiledMap::create(path);
if (tmx)
{
//prevent that editor's data does not match in size and resources

View File

@ -131,7 +131,7 @@ list(APPEND GAME_HEADER
Classes/MaterialSystemTest/MaterialSystemTest.h
Classes/IntervalTest/IntervalTest.h
Classes/TileMapTest/TileMapTest2.h
Classes/TileMapTest/TileMapTest.h
# Classes/TileMapTest/TileMapTest.h
Classes/NewEventDispatcherTest/NewEventDispatcherTest.h
Classes/ActionsProgressTest/ActionsProgressTest.h
Classes/RotateWorldTest/RotateWorldTest.h
@ -291,7 +291,7 @@ list(APPEND GAME_SOURCE
Classes/Texture2dTest/Texture2dTest.cpp
Classes/TextureCacheTest/TextureCacheTest.cpp
Classes/TexturePackerEncryptionTest/TextureAtlasEncryptionTest.cpp
Classes/TileMapTest/TileMapTest.cpp
#Classes/TileMapTest/TileMapTest.cpp
Classes/TileMapTest/TileMapTest2.cpp
Classes/TouchesTest/Ball.cpp
Classes/TouchesTest/Paddle.cpp

File diff suppressed because it is too large Load Diff

View File

@ -1,415 +0,0 @@
/****************************************************************************
Copyright (c) 2017-2018 Xiamen Yaji Software Co., Ltd.
http://www.cocos2d-x.org
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
****************************************************************************/
#ifndef _TILEMAP_TEST_H_
#define _TILEMAP_TEST_H_
#include "../BaseTest.h"
DEFINE_TEST_SUITE(TileMapTests);
class TileDemo : public TestCase
{
public:
TileDemo();
virtual ~TileDemo();
virtual std::string title() const override;
virtual std::string subtitle() const override;
virtual void onExit() override;
void onTouchesMoved(const std::vector<cocos2d::Touch*>& touches, cocos2d::Event* event);
};
class TileMapTest : public TileDemo
{
public:
CREATE_FUNC(TileMapTest);
TileMapTest();
virtual std::string title() const override;
};
class TileMapEditTest : public TileDemo
{
public:
CREATE_FUNC(TileMapEditTest);
TileMapEditTest ();
virtual std::string title() const override;
void updateMap(float dt);
};
class TMXOrthoTest : public TileDemo
{
public:
CREATE_FUNC(TMXOrthoTest);
TMXOrthoTest();
virtual std::string title() const override;
virtual void onEnter() override;
virtual void onExit() override;
};
class TMXStaggeredTest : public TileDemo
{
public:
CREATE_FUNC(TMXStaggeredTest);
TMXStaggeredTest();
virtual std::string title() const override;
virtual void onEnter() override;
virtual void onExit() override;
};
class TMXOrthoTest2 : public TileDemo
{
public:
CREATE_FUNC(TMXOrthoTest2);
TMXOrthoTest2();
virtual std::string title() const override;
};
class TMXOrthoTest3 : public TileDemo
{
public:
CREATE_FUNC(TMXOrthoTest3);
TMXOrthoTest3();
virtual std::string title() const override;
};
class TMXOrthoTest4 : public TileDemo
{
public:
CREATE_FUNC(TMXOrthoTest4);
TMXOrthoTest4();
void removeSprite(float dt);
virtual std::string title() const override;
};
class TMXReadWriteTest : public TileDemo
{
unsigned int _gid;
unsigned int _gid2;
public:
CREATE_FUNC(TMXReadWriteTest);
TMXReadWriteTest();
virtual std::string title() const override;
void removeSprite(Node* sender);
void updateCol(float dt);
void repaintWithGID(float dt);
void removeTiles(float dt);
};
class TMXHexTest : public TileDemo
{
public:
CREATE_FUNC(TMXHexTest);
TMXHexTest();
virtual std::string title() const override;
};
class TMXIsoTest : public TileDemo
{
public:
CREATE_FUNC(TMXIsoTest);
TMXIsoTest();
virtual std::string title() const override;
};
class TMXIsoTest1 : public TileDemo
{
public:
CREATE_FUNC(TMXIsoTest1);
TMXIsoTest1();
virtual std::string title() const override;
};
class TMXIsoTest2 : public TileDemo
{
public:
CREATE_FUNC(TMXIsoTest2);
TMXIsoTest2();
virtual std::string title() const override;
};
class TMXUncompressedTest : public TileDemo
{
public:
CREATE_FUNC(TMXUncompressedTest);
TMXUncompressedTest();
virtual std::string title() const override;
};
class TMXTilesetTest : public TileDemo
{
public:
CREATE_FUNC(TMXTilesetTest);
TMXTilesetTest();
virtual std::string title() const override;
};
class TMXCvsFormatTest : public TileDemo
{
public:
CREATE_FUNC(TMXCvsFormatTest);
TMXCvsFormatTest();
virtual std::string title() const override;
};
class TMXOrthoObjectsTest : public TileDemo
{
public:
CREATE_FUNC(TMXOrthoObjectsTest);
TMXOrthoObjectsTest();
virtual std::string title() const override;
virtual std::string subtitle() const override;
};
class TMXIsoObjectsTest : public TileDemo
{
public:
CREATE_FUNC(TMXIsoObjectsTest);
TMXIsoObjectsTest();
virtual std::string title() const override;
virtual std::string subtitle() const override;
};
class TMXResizeTest : public TileDemo
{
public:
CREATE_FUNC(TMXResizeTest);
TMXResizeTest();
virtual std::string title() const override;
virtual std::string subtitle() const override;
};
class TMXIsoZorder : public TileDemo
{
cocos2d::Sprite* _tamara;
public:
CREATE_FUNC(TMXIsoZorder);
TMXIsoZorder();
virtual std::string title() const override;
virtual std::string subtitle() const override;
virtual void onExit()override;
~TMXIsoZorder();
void repositionSprite(float dt);
};
class TMXOrthoZorder : public TileDemo
{
cocos2d::Sprite* _tamara;
public:
CREATE_FUNC(TMXOrthoZorder);
TMXOrthoZorder();
virtual std::string title() const override;
virtual std::string subtitle() const override;
virtual ~TMXOrthoZorder();
void repositionSprite(float dt);
};
class TMXIsoVertexZ : public TileDemo
{
cocos2d::Sprite* _tamara;
public:
CREATE_FUNC(TMXIsoVertexZ);
TMXIsoVertexZ();
virtual std::string title() const override;
virtual std::string subtitle() const override;
~TMXIsoVertexZ();
void repositionSprite(float dt);
virtual void onEnter() override;
virtual void onExit() override;
};
class TMXOrthoVertexZ : public TileDemo
{
cocos2d::Sprite* _tamara;
public:
CREATE_FUNC(TMXOrthoVertexZ);
TMXOrthoVertexZ();
virtual std::string title() const override;
virtual std::string subtitle() const override;
~TMXOrthoVertexZ();
void repositionSprite(float dt);
virtual void onEnter() override;
virtual void onExit() override;
};
class TMXIsoMoveLayer : public TileDemo
{
public:
CREATE_FUNC(TMXIsoMoveLayer);
TMXIsoMoveLayer();
virtual std::string title() const override;
virtual std::string subtitle() const override;
};
class TMXOrthoMoveLayer : public TileDemo
{
public:
CREATE_FUNC(TMXOrthoMoveLayer);
TMXOrthoMoveLayer();
virtual std::string title() const override;
virtual std::string subtitle() const override;
};
class TMXTilePropertyTest : public TileDemo
{
public:
CREATE_FUNC(TMXTilePropertyTest);
TMXTilePropertyTest();
virtual std::string title() const override;
virtual std::string subtitle() const override;
};
class TMXOrthoFlipTest : public TileDemo
{
public:
CREATE_FUNC(TMXOrthoFlipTest);
TMXOrthoFlipTest();
virtual std::string title() const override;
};
class TMXOrthoFlipRunTimeTest : public TileDemo
{
public:
CREATE_FUNC(TMXOrthoFlipRunTimeTest);
TMXOrthoFlipRunTimeTest();
virtual std::string title() const override;
virtual std::string subtitle() const override;
void flipIt(float dt);
};
class TMXOrthoFromXMLTest : public TileDemo
{
public:
CREATE_FUNC(TMXOrthoFromXMLTest);
TMXOrthoFromXMLTest();
virtual std::string title() const override;
};
class TMXOrthoXMLFormatTest : public TileDemo
{
public:
CREATE_FUNC(TMXOrthoXMLFormatTest);
TMXOrthoXMLFormatTest();
virtual std::string title() const override;
};
class TMXBug987 : public TileDemo
{
public:
CREATE_FUNC(TMXBug987);
TMXBug987();
virtual std::string title() const override;
virtual std::string subtitle() const override;
};
class TMXBug787 : public TileDemo
{
public:
CREATE_FUNC(TMXBug787);
TMXBug787();
virtual std::string title() const override;
virtual std::string subtitle() const override;
};
class TMXGIDObjectsTest : public TileDemo
{
public:
CREATE_FUNC(TMXGIDObjectsTest);
TMXGIDObjectsTest();
virtual std::string title() const override;
virtual std::string subtitle() const override;
};
class TMXHexOddXTest : public TileDemo
{
public:
CREATE_FUNC(TMXHexOddXTest);
TMXHexOddXTest();
virtual std::string title() const override;
};
class TMXHexOddYTest : public TileDemo
{
public:
CREATE_FUNC(TMXHexOddYTest);
TMXHexOddYTest();
virtual std::string title() const override;
};
class TMXHexEvenXTest : public TileDemo
{
public:
CREATE_FUNC(TMXHexEvenXTest);
TMXHexEvenXTest();
virtual std::string title() const override;
};
class TMXHexEvenYTest : public TileDemo
{
public:
CREATE_FUNC(TMXHexEvenYTest);
TMXHexEvenYTest();
virtual std::string title() const override;
};
class TMXHexAxisXTest : public TileDemo
{
public:
CREATE_FUNC(TMXHexAxisXTest);
TMXHexAxisXTest();
virtual std::string title() const override;
};
class Issue16105Test : public TileDemo
{
public:
CREATE_FUNC(Issue16105Test);
Issue16105Test();
virtual std::string title() const override;
};
class Issue16512Test : public TileDemo
{
public:
CREATE_FUNC(Issue16512Test);
Issue16512Test();
virtual std::string title() const override;
};
#endif

View File

@ -66,6 +66,7 @@ FastTileMapTests::FastTileMapTests()
ADD_TEST_CASE(TMXBug987New);
ADD_TEST_CASE(TMXBug787New);
ADD_TEST_CASE(TMXGIDObjectsTestNew);
ADD_TEST_CASE(TileAnimTestNew);
}
TileDemoNew::TileDemoNew()
@ -1386,3 +1387,35 @@ std::string TMXGIDObjectsTestNew::subtitle() const
{
return "Tiles are created from an object group";
}
//------------------------------------------------------------------
//
// TileAnimTestNew
//
//------------------------------------------------------------------
TileAnimTestNew::TileAnimTestNew()
{
map = FastTMXTiledMap::create("TileMaps/tile_animation_test.tmx");
addChild(map, 0, kTagTileMap);
auto listener = EventListenerTouchAllAtOnce::create();
listener->onTouchesBegan = CC_CALLBACK_2(TileAnimTestNew::onTouchBegan, this);
_eventDispatcher->addEventListenerWithSceneGraphPriority(listener, this);
Size CC_UNUSED s = map->getContentSize();
CCLOG("ContentSize: %f, %f", s.width, s.height);
map->setTileAnimEnabled(_animStarted);
}
std::string TileAnimTestNew::title() const
{
return "Tile animation test. Click to toggle the animation";
}
void TileAnimTestNew::onTouchBegan(const std::vector<cocos2d::Touch*>& touches, cocos2d::Event* event)
{
_animStarted = !_animStarted;
map->setTileAnimEnabled(_animStarted);
}

View File

@ -334,4 +334,16 @@ public:
virtual std::string subtitle() const override;
};
class TileAnimTestNew : public TileDemoNew
{
public:
CREATE_FUNC(TileAnimTestNew);
TileAnimTestNew();
virtual std::string title() const override;
cocos2d::FastTMXTiledMap* map;
bool _animStarted = true;
void onTouchBegan(const std::vector<cocos2d::Touch*>& touches, cocos2d::Event* event);
};
#endif

View File

@ -96,7 +96,6 @@ public:
addTest("Node: Sprite3D", [](){ return new Sprite3DTests(); });
addTest("Node: SpritePolygon", [](){return new (std::nothrow) SpritePolygonTest(); });
addTest("Node: Terrain", [](){ return new TerrainTests(); });
addTest("Node: TileMap", [](){return new TileMapTests(); });
addTest("Node: FastTileMap", [](){return new FastTileMapTests(); });
addTest("Node: Text Input", [](){return new TextInputTests(); });
addTest("Node: UI", [](){ return new UITests(); });

View File

@ -109,7 +109,6 @@
#include "Texture2dTest/Texture2dTest.h"
#include "TextureCacheTest/TextureCacheTest.h"
#include "TexturePackerEncryptionTest/TextureAtlasEncryptionTest.h"
#include "TileMapTest/TileMapTest.h"
#include "TileMapTest/TileMapTest2.h"
#include "TouchesTest/TouchesTest.h"
#include "TransitionsTest/TransitionsTest.h"

View File

@ -0,0 +1,33 @@
<?xml version="1.0" encoding="UTF-8"?>
<map version="1.2" tiledversion="1.2.5" orientation="orthogonal" renderorder="right-down" width="10" height="10" tilewidth="32" tileheight="32" infinite="0" nextlayerid="4" nextobjectid="1">
<tileset firstgid="1" name="tileset" tilewidth="32" tileheight="32" spacing="1" margin="1" tilecount="48" columns="8">
<image source="./tmw_desert_spacing.png" width="265" height="199"/>
<tile id="0">
<animation>
<frame tileid="37" duration="200"/>
<frame tileid="39" duration="200"/>
</animation>
</tile>
<tile id="1">
<animation>
<frame tileid="46" duration="200"/>
<frame tileid="47" duration="200"/>
</animation>
</tile>
</tileset>
<layer id="1" name="Tile Layer 1" width="10" height="10">
<data encoding="base64" compression="zlib">
eJyTY2BgkBvFgwYDAEFHC7k=
</data>
</layer>
<layer id="2" name="Tile Layer 2" width="10" height="10">
<data encoding="base64" compression="zlib">
eJxjYCAeMBLAtFI3kgAAHeAAGQ==
</data>
</layer>
<layer id="3" name="Tile Layer 3" width="10" height="10">
<data encoding="base64" compression="zlib">
eJxjYBg+gIkAppU6agIAHDAAMQ==
</data>
</layer>
</map>