Skip to content

Commit 7481986

Browse files
committed
animated tile feature from v3
1 parent 7a5282a commit 7481986

File tree

7 files changed

+317
-1
lines changed

7 files changed

+317
-1
lines changed

cocos/2d/CCTMXLayer.cpp

Lines changed: 101 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -220,9 +220,18 @@ void TMXLayer::setupTiles()
220220
if (gid != 0)
221221
{
222222
this->appendTileForGID(gid, Vec2(newX, y));
223+
if(_tileSet->_animationInfo.at(gid))
224+
{
225+
_animTileCoord[gid].push_back(Vec2(newX, y));
226+
}
223227
}
224228
}
225229
}
230+
if(hasTileAnimation())
231+
{
232+
_tileAnimManager = TMXTileAnimManager::create(this);
233+
CC_SAFE_RETAIN(_tileAnimManager);
234+
}
226235
}
227236

228237
// TMXLayer - Properties
@@ -843,5 +852,97 @@ std::string TMXLayer::getDescription() const
843852
return StringUtils::format("<TMXLayer | tag = %d, size = %d,%d>", _tag, (int)_mapTileSize.width, (int)_mapTileSize.height);
844853
}
845854

855+
TMXTileAnimManager::TMXTileAnimManager(TMXLayer *layer)
856+
{
857+
_layer = layer;
858+
for(const auto &p : *_layer->getAnimTileCoord())
859+
{
860+
for(auto tilePos : p.second)
861+
{
862+
_tasks.pushBack(TMXTileAnimTask::create(_layer, _layer->getTileSet()->_animationInfo.at(p.first), tilePos));
863+
}
864+
}
865+
}
866+
867+
TMXTileAnimManager *TMXTileAnimManager::create(TMXLayer *layer)
868+
{
869+
TMXTileAnimManager *ret = new (std::nothrow) TMXTileAnimManager(layer);
870+
if (ret)
871+
{
872+
ret->autorelease();
873+
return ret;
874+
}
875+
CC_SAFE_DELETE(ret);
876+
return nullptr;
877+
}
878+
879+
void TMXTileAnimManager::startAll()
880+
{
881+
if(_started || _tasks.empty())
882+
return;
883+
_started = true;
884+
for(auto &task : _tasks)
885+
{
886+
task->start();
887+
}
888+
}
889+
890+
void TMXTileAnimManager::stopAll()
891+
{
892+
if(!_started)
893+
return;
894+
_started = false;
895+
for(auto &task : _tasks)
896+
{
897+
task->stop();
898+
}
899+
}
900+
901+
TMXTileAnimTask::TMXTileAnimTask(TMXLayer *layer, TMXTileAnimInfo *animation, const Vec2 &tilePos)
902+
{
903+
_layer = layer;
904+
_animation = animation;
905+
_frameCount = static_cast<uint32_t>(_animation->_frames.size());
906+
_tilePosition = tilePos;
907+
std::stringstream ss;
908+
ss << "TickAnimOnTilePos(" << _tilePosition.x << "," << _tilePosition.y << ")";
909+
_key = ss.str();
910+
}
911+
912+
void TMXTileAnimTask::tickAndScheduleNext(float dt)
913+
{
914+
setCurrFrame();
915+
_layer->getParent()->scheduleOnce(CC_CALLBACK_1(TMXTileAnimTask::tickAndScheduleNext, this), _animation->_frames[_currentFrame]._duration/1000.0f, _key);
916+
}
917+
918+
void TMXTileAnimTask::start()
919+
{
920+
_isRunning = true;
921+
tickAndScheduleNext(0.0f);
922+
}
923+
924+
void TMXTileAnimTask::stop()
925+
{
926+
_isRunning = false;
927+
_layer->getParent()->unschedule(_key);
928+
}
929+
930+
void TMXTileAnimTask::setCurrFrame()
931+
{
932+
_layer->setTileGID(_animation->_frames[_currentFrame]._tileID, _tilePosition);
933+
_currentFrame = (_currentFrame + 1) % _frameCount;
934+
}
935+
936+
TMXTileAnimTask *TMXTileAnimTask::create(TMXLayer *layer, TMXTileAnimInfo *animation, const Vec2 &tilePos)
937+
{
938+
TMXTileAnimTask *ret = new (std::nothrow) TMXTileAnimTask(layer, animation, tilePos);
939+
if (ret)
940+
{
941+
ret->autorelease();
942+
return ret;
943+
}
944+
CC_SAFE_DELETE(ret);
945+
return nullptr;
946+
}
846947

847948
NS_CC_END

cocos/2d/CCTMXLayer.h

Lines changed: 83 additions & 0 deletions
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
/**
@@ -276,6 +277,22 @@ class CC_DLL TMXLayer : public SpriteBatchNode
276277
*/
277278
virtual std::string getDescription() const override;
278279

280+
/** Map from gid of animated tile to its instance.
281+
*
282+
* @return Map from gid of animated tile to its instance.
283+
*/
284+
const std::map<uint32_t, std::vector<Vec2>>* getAnimTileCoord() {
285+
return &_animTileCoord;
286+
}
287+
288+
bool hasTileAnimation() const {
289+
return !_animTileCoord.empty();
290+
}
291+
292+
TMXTileAnimManager* getTileAnimManager() const {
293+
return _tileAnimManager;
294+
}
295+
279296
protected:
280297
Vec2 getPositionForIsoAt(const Vec2& pos);
281298
Vec2 getPositionForOrthoAt(const Vec2& pos);
@@ -337,6 +354,72 @@ class CC_DLL TMXLayer : public SpriteBatchNode
337354
ValueMap _properties;
338355
};
339356

357+
/** map from gid of animated tile to its instance. Also useful for optimization*/
358+
std::map<uint32_t, std::vector<Vec2>> _animTileCoord;
359+
/** pointer to the tile animation manager of this layer */
360+
TMXTileAnimManager *_tileAnimManager = nullptr;
361+
};
362+
363+
/** @brief TMXTileAnimTask represents the frame-tick task of an animated tile.
364+
* It is a assistant class for TMXTileAnimTicker.
365+
*/
366+
class CC_DLL TMXTileAnimTask : public Ref
367+
{
368+
public:
369+
TMXTileAnimTask(TMXLayer *layer, TMXTileAnimInfo *animation, const Vec2 &tilePos);
370+
static TMXTileAnimTask * create(TMXLayer *layer, TMXTileAnimInfo *animation, const Vec2 &tilePos);
371+
/** start the animation task */
372+
void start();
373+
/** stop the animation task */
374+
void stop();
375+
bool isRunning() const {
376+
return _isRunning;
377+
}
378+
379+
protected:
380+
/** set texture of tile to current frame */
381+
void setCurrFrame();
382+
/** tick to next frame and schedule next tick */
383+
void tickAndScheduleNext(float dt);
384+
385+
bool _isRunning = false;
386+
/** key of schedule task for specific animated tile */
387+
std::string _key;
388+
TMXLayer *_layer = nullptr;
389+
/** position of the animated tile */
390+
Vec2 _tilePosition;
391+
/** AnimationInfo on this tile */
392+
TMXTileAnimInfo *_animation = nullptr;
393+
/** Index of the frame that should be drawn currently */
394+
uint32_t _currentFrame = 0;
395+
uint32_t _frameCount = 0;
396+
};
397+
398+
/** @brief TMXTileAnimManager controls all tile animation of a layer.
399+
*/
400+
class CC_DLL TMXTileAnimManager : public Ref
401+
{
402+
public:
403+
static TMXTileAnimManager * create(TMXLayer *layer);
404+
explicit TMXTileAnimManager(TMXLayer *layer);
405+
406+
/** start all tile animations */
407+
void startAll();
408+
/** stop all tile animations */
409+
void stopAll();
410+
411+
/** get vector of tasks */
412+
const Vector<TMXTileAnimTask*>& getTasks() const {
413+
return _tasks;
414+
}
415+
416+
protected:
417+
bool _started = false;
418+
/** vector contains all tasks of this layer */
419+
Vector<TMXTileAnimTask*> _tasks;
420+
TMXLayer* _layer = nullptr;
421+
};
422+
340423
// end of tilemap_parallax_nodes group
341424
/** @} */
342425

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: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -260,6 +260,12 @@ class CC_DLL TMXTiledMap : public Node
260260
int getLayerNum();
261261
const std::string& getResourceFile() const { return _tmxFile; }
262262

263+
/** Set all tile animations enabled or not.
264+
* animations are not enabled by default
265+
*/
266+
void setTileAnimEnabled(bool enabled);
267+
268+
263269
CC_CONSTRUCTOR_ACCESS:
264270
/**
265271
* @js ctor

cocos/2d/CCTMXXMLParser.cpp

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -665,6 +665,19 @@ void TMXMapInfo::startElement(void* /*ctx*/, const char *name, const char **atts
665665
dict["polylinePoints"] = Value(pointsArray);
666666
}
667667
}
668+
else if(elementName == "animation")
669+
{
670+
TMXTilesetInfo* info = tmxMapInfo->getTilesets().back();
671+
info->_animationInfo.insert(tmxMapInfo->getParentGID(), TMXTileAnimInfo::create(tmxMapInfo->getParentGID()));
672+
tmxMapInfo->setParentElement(TMXPropertyAnimation);
673+
}
674+
else if(elementName == "frame")
675+
{
676+
TMXTilesetInfo* info = tmxMapInfo->getTilesets().back();
677+
auto animInfo = info->_animationInfo.at(tmxMapInfo->getParentGID());
678+
// calculate gid of frame
679+
animInfo->_frames.emplace_back(TMXTileAnimFrame(info->_firstGid + attributeDict["tileid"].asInt(), attributeDict["duration"].asFloat()));
680+
}
668681
}
669682

670683
void TMXMapInfo::endElement(void* /*ctx*/, const char *name)
@@ -791,6 +804,10 @@ void TMXMapInfo::endElement(void* /*ctx*/, const char *name)
791804
{
792805
_recordFirstGID = true;
793806
}
807+
else if (elementName == "animation")
808+
{
809+
tmxMapInfo->setParentElement(TMXPropertyNone);
810+
}
794811
}
795812

796813
void TMXMapInfo::textHandler(void* /*ctx*/, const char *ch, size_t len)
@@ -806,4 +823,27 @@ void TMXMapInfo::textHandler(void* /*ctx*/, const char *ch, size_t len)
806823
}
807824
}
808825

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

cocos/2d/CCTMXXMLParser.h

Lines changed: 36 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,9 @@ enum {
7273
TMXPropertyLayer,
7374
TMXPropertyObjectGroup,
7475
TMXPropertyObject,
75-
TMXPropertyTile
76+
TMXPropertyTile,
77+
TMXPropertyTile,
78+
TMXPropertyAnimation
7679
};
7780

7881
typedef enum TMXTileFlags_ {
@@ -119,6 +122,35 @@ class CC_DLL TMXLayerInfo : public Ref
119122
Vec2 _offset;
120123
};
121124

125+
/** @brief TMXTileAnimFrame contains the information about the frame of a animated tile like:
126+
- Frame gid
127+
- duration of this frame
128+
129+
This information is obtained from the TMX file.
130+
*/
131+
struct CC_DLL TMXTileAnimFrame
132+
{
133+
TMXTileAnimFrame(uint32_t tileID, float duration);
134+
/** gid of the frame */
135+
uint32_t _tileID = 0;
136+
/** duration of the frame */
137+
float _duration = 0.0f;
138+
};
139+
140+
/** @brief TMXTileAnimInfo contains the information about the animated tile like:
141+
- Animated Tile gid
142+
- frames the animated tile contains
143+
144+
This information is obtained from the TMX file.
145+
*/
146+
struct CC_DLL TMXTileAnimInfo : public Ref
147+
{
148+
static TMXTileAnimInfo * create(uint32_t tileID);
149+
explicit TMXTileAnimInfo(uint32_t tileID);
150+
uint32_t _tileID = 0;
151+
std::vector<TMXTileAnimFrame> _frames;
152+
};
153+
122154
/** @brief TMXTilesetInfo contains the information about the tilesets like:
123155
- Tileset name
124156
- Tileset spacing
@@ -143,6 +175,9 @@ class CC_DLL TMXTilesetInfo : public Ref
143175
//! size in pixels of the image
144176
Size _imageSize;
145177
std::string _originSourceImage;
178+
//! map from gid of animated tile to its animation info
179+
Map<uint32_t, TMXTileAnimInfo*> _animationInfo;
180+
146181

147182
public:
148183
/**

0 commit comments

Comments
 (0)