Skip to content

Commit 8708e82

Browse files
DEAGS3000minggo
authored andcommitted
Added tmx animated tile support, with test case. (#20315)
* Added tmx animated tile support, with test case. Tile animation are disabled by default, if user didn't enable it, the TMXTiledMap class will do just the same as this support not exists, no additional render resources needed. The tile animations are still rendered through SpriteBatchNode, no additional draw call needed. * changed tileset tococos own's * used cocos2dx own's tileset * changed return type of TMXLayer::getAnimTileCoord to pointer for lua api converting * deleted useless code, improved api * re-generated script binding * added CC_DLL to new classes, solved some problem posted on pull request * changed return type of getTasks to pointer * made TileAnimTask inherit form Ref * removed a fixed FIXME * added const to getTasks, deleted unneeded empty lines, re-generated script bindings * deleted empty lines in TMXXMLParser
1 parent cdfc781 commit 8708e82

File tree

13 files changed

+1628
-126
lines changed

13 files changed

+1628
-126
lines changed

cocos/2d/CCTMXLayer.cpp

Lines changed: 147 additions & 46 deletions
Large diffs are not rendered by default.

cocos/2d/CCTMXLayer.h

Lines changed: 82 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,7 @@ NS_CC_BEGIN
3636
class TMXMapInfo;
3737
class TMXLayerInfo;
3838
class TMXTilesetInfo;
39+
class TMXTileAnimManager;
3940
struct _ccCArray;
4041

4142
/**
@@ -294,6 +295,22 @@ class CC_DLL TMXLayer : public SpriteBatchNode
294295
*/
295296
virtual std::string getDescription() const override;
296297

298+
/** Map from gid of animated tile to its instance.
299+
*
300+
* @return Map from gid of animated tile to its instance.
301+
*/
302+
const std::map<uint32_t, std::vector<Vec2>>* getAnimTileCoord() {
303+
return &_animTileCoord;
304+
}
305+
306+
bool hasTileAnimation() const {
307+
return !_animTileCoord.empty();
308+
}
309+
310+
TMXTileAnimManager* getTileAnimManager() const {
311+
return _tileAnimManager;
312+
}
313+
297314
protected:
298315
Vec2 getPositionForIsoAt(const Vec2& pos);
299316
Vec2 getPositionForOrthoAt(const Vec2& pos);
@@ -353,6 +370,71 @@ class CC_DLL TMXLayer : public SpriteBatchNode
353370
int _hexSideLength;
354371
/** properties from the layer. They can be added using Tiled */
355372
ValueMap _properties;
373+
374+
/** map from gid of animated tile to its instance. Also useful for optimization*/
375+
std::map<uint32_t, std::vector<Vec2>> _animTileCoord;
376+
/** pointer to the tile animation manager of this layer */
377+
TMXTileAnimManager *_tileAnimManager = nullptr;
378+
};
379+
380+
/** @brief TMXTileAnimTask represents the frame-tick task of an animated tile.
381+
* It is a assistant class for TMXTileAnimTicker.
382+
*/
383+
class CC_DLL TMXTileAnimTask : public Ref
384+
{
385+
public:
386+
TMXTileAnimTask(TMXLayer *layer, TMXTileAnimInfo *animation, const Vec2 &tilePos);
387+
static TMXTileAnimTask * create(TMXLayer *layer, TMXTileAnimInfo *animation, const Vec2 &tilePos);
388+
/** start the animation task */
389+
void start();
390+
/** stop the animation task */
391+
void stop();
392+
bool isRunning() const {
393+
return _isRunning;
394+
}
395+
396+
protected:
397+
/** set texture of tile to current frame */
398+
void setCurrFrame();
399+
/** tick to next frame and schedule next tick */
400+
void tickAndScheduleNext(float dt);
401+
402+
bool _isRunning = false;
403+
/** key of schedule task for specific animated tile */
404+
std::string _key;
405+
TMXLayer *_layer = nullptr;
406+
/** position of the animated tile */
407+
Vec2 _tilePosition;
408+
/** AnimationInfo on this tile */
409+
TMXTileAnimInfo *_animation = nullptr;
410+
/** Index of the frame that should be drawn currently */
411+
uint32_t _currentFrame = 0;
412+
uint32_t _frameCount = 0;
413+
};
414+
415+
/** @brief TMXTileAnimManager controls all tile animation of a layer.
416+
*/
417+
class CC_DLL TMXTileAnimManager : public Ref
418+
{
419+
public:
420+
static TMXTileAnimManager * create(TMXLayer *layer);
421+
explicit TMXTileAnimManager(TMXLayer *layer);
422+
423+
/** start all tile animations */
424+
void startAll();
425+
/** stop all tile animations */
426+
void stopAll();
427+
428+
/** get vector of tasks */
429+
const Vector<TMXTileAnimTask*>& getTasks() const {
430+
return _tasks;
431+
}
432+
433+
protected:
434+
bool _started = false;
435+
/** vector contains all tasks of this layer */
436+
Vector<TMXTileAnimTask*> _tasks;
437+
TMXLayer* _layer = nullptr;
356438
};
357439

358440
// end of tilemap_parallax_nodes group
@@ -361,4 +443,3 @@ class CC_DLL TMXLayer : public SpriteBatchNode
361443
NS_CC_END
362444

363445
#endif //__CCTMX_LAYER_H__
364-

cocos/2d/CCTMXTiledMap.cpp

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -273,4 +273,22 @@ int TMXTiledMap::getLayerNum()
273273
return _tmxLayerNum;
274274
}
275275

276+
void TMXTiledMap::setTileAnimEnabled(bool enabled)
277+
{
278+
for (auto& child : _children)
279+
{
280+
TMXLayer* layer = dynamic_cast<TMXLayer*>(child);
281+
if(layer)
282+
{
283+
if(layer->hasTileAnimation())
284+
{
285+
if(enabled)
286+
layer->getTileAnimManager()->startAll();
287+
else
288+
layer->getTileAnimManager()->stopAll();
289+
}
290+
}
291+
}
292+
}
293+
276294
NS_CC_END

cocos/2d/CCTMXTiledMap.h

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -276,6 +276,11 @@ class CC_DLL TMXTiledMap : public Node
276276
int getLayerNum();
277277
const std::string& getResourceFile() const { return _tmxFile; }
278278

279+
/** Set all tile animations enabled or not.
280+
* animations are not enabled by default
281+
*/
282+
void setTileAnimEnabled(bool enabled);
283+
279284
CC_CONSTRUCTOR_ACCESS:
280285
/**
281286
* @js ctor

cocos/2d/CCTMXXMLParser.cpp

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -672,6 +672,19 @@ void TMXMapInfo::startElement(void* /*ctx*/, const char *name, const char **atts
672672
dict["polylinePoints"] = Value(pointsArray);
673673
}
674674
}
675+
else if(elementName == "animation")
676+
{
677+
TMXTilesetInfo* info = tmxMapInfo->getTilesets().back();
678+
info->_animationInfo.insert(tmxMapInfo->getParentGID(), TMXTileAnimInfo::create(tmxMapInfo->getParentGID()));
679+
tmxMapInfo->setParentElement(TMXPropertyAnimation);
680+
}
681+
else if(elementName == "frame")
682+
{
683+
TMXTilesetInfo* info = tmxMapInfo->getTilesets().back();
684+
auto animInfo = info->_animationInfo.at(tmxMapInfo->getParentGID());
685+
// calculate gid of frame
686+
animInfo->_frames.emplace_back(TMXTileAnimFrame(info->_firstGid + attributeDict["tileid"].asInt(), attributeDict["duration"].asFloat()));
687+
}
675688
}
676689

677690
void TMXMapInfo::endElement(void* /*ctx*/, const char *name)
@@ -792,6 +805,10 @@ void TMXMapInfo::endElement(void* /*ctx*/, const char *name)
792805
{
793806
_recordFirstGID = true;
794807
}
808+
else if (elementName == "animation")
809+
{
810+
tmxMapInfo->setParentElement(TMXPropertyNone);
811+
}
795812
}
796813

797814
void TMXMapInfo::textHandler(void* /*ctx*/, const char *ch, size_t len)
@@ -807,4 +824,27 @@ void TMXMapInfo::textHandler(void* /*ctx*/, const char *ch, size_t len)
807824
}
808825
}
809826

827+
TMXTileAnimFrame::TMXTileAnimFrame(uint32_t tileID, float duration)
828+
: _tileID(tileID)
829+
, _duration(duration)
830+
{
831+
}
832+
833+
TMXTileAnimInfo::TMXTileAnimInfo(uint32_t tileID)
834+
: _tileID(tileID)
835+
{
836+
}
837+
838+
TMXTileAnimInfo *TMXTileAnimInfo::create(uint32_t tileID)
839+
{
840+
TMXTileAnimInfo *ret = new (std::nothrow) TMXTileAnimInfo(tileID);
841+
if (ret)
842+
{
843+
ret->autorelease();
844+
return ret;
845+
}
846+
CC_SAFE_DELETE(ret);
847+
return nullptr;
848+
}
849+
810850
NS_CC_END

cocos/2d/CCTMXXMLParser.h

Lines changed: 35 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,7 @@ THE SOFTWARE.
3636
#include "platform/CCSAXParser.h"
3737
#include "base/CCVector.h"
3838
#include "base/CCValue.h"
39+
#include "base/CCMap.h"
3940
#include "2d/CCTMXObjectGroup.h" // needed for Vector<TMXObjectGroup*> for binding
4041

4142
#include <string>
@@ -72,7 +73,8 @@ enum {
7273
TMXPropertyLayer,
7374
TMXPropertyObjectGroup,
7475
TMXPropertyObject,
75-
TMXPropertyTile
76+
TMXPropertyTile,
77+
TMXPropertyAnimation
7678
};
7779

7880
typedef enum TMXTileFlags_ {
@@ -119,6 +121,35 @@ class CC_DLL TMXLayerInfo : public Ref
119121
Vec2 _offset;
120122
};
121123

124+
/** @brief TMXTileAnimFrame contains the information about the frame of a animated tile like:
125+
- Frame gid
126+
- duration of this frame
127+
128+
This information is obtained from the TMX file.
129+
*/
130+
struct CC_DLL TMXTileAnimFrame
131+
{
132+
TMXTileAnimFrame(uint32_t tileID, float duration);
133+
/** gid of the frame */
134+
uint32_t _tileID = 0;
135+
/** duration of the frame */
136+
float _duration = 0.0f;
137+
};
138+
139+
/** @brief TMXTileAnimInfo contains the information about the animated tile like:
140+
- Animated Tile gid
141+
- frames the animated tile contains
142+
143+
This information is obtained from the TMX file.
144+
*/
145+
struct CC_DLL TMXTileAnimInfo : public Ref
146+
{
147+
static TMXTileAnimInfo * create(uint32_t tileID);
148+
explicit TMXTileAnimInfo(uint32_t tileID);
149+
uint32_t _tileID = 0;
150+
std::vector<TMXTileAnimFrame> _frames;
151+
};
152+
122153
/** @brief TMXTilesetInfo contains the information about the tilesets like:
123154
- Tileset name
124155
- Tileset spacing
@@ -144,6 +175,9 @@ class CC_DLL TMXTilesetInfo : public Ref
144175
Size _imageSize;
145176
std::string _originSourceImage;
146177

178+
//! map from gid of animated tile to its animation info
179+
Map<uint32_t, TMXTileAnimInfo*> _animationInfo;
180+
147181
public:
148182
/**
149183
* @js ctor

0 commit comments

Comments
 (0)