mirror of https://github.com/axmolengine/axmol.git
Sync missing feature from v3, and API compatible
This commit is contained in:
parent
ae99a5965b
commit
8b7505e171
|
@ -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
|
||||
|
|
|
@ -37,6 +37,7 @@ NS_CC_BEGIN
|
|||
class TMXMapInfo;
|
||||
class TMXLayerInfo;
|
||||
class TMXTilesetInfo;
|
||||
class TMXTileAnimManager;
|
||||
class Texture2D;
|
||||
class Sprite;
|
||||
|
||||
|
@ -275,6 +276,21 @@ 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;
|
||||
}
|
||||
protected:
|
||||
virtual void setOpacity(uint8_t opacity) override;
|
||||
|
||||
|
@ -315,9 +331,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 +379,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
|
||||
|
|
|
@ -257,4 +257,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
|
||||
|
|
|
@ -201,6 +201,10 @@ public:
|
|||
|
||||
virtual std::string getDescription() const override;
|
||||
|
||||
/** Set all tile animations enabled or not.
|
||||
* animations are not enabled by default
|
||||
*/
|
||||
void setTileAnimEnabled(bool enabled);
|
||||
protected:
|
||||
/**
|
||||
* @js ctor
|
||||
|
@ -243,6 +247,8 @@ private:
|
|||
|
||||
// end of tilemap_parallax_nodes group
|
||||
/** @} */
|
||||
|
||||
|
||||
// @API compatible
|
||||
typedef FastTMXTiledMap TMXTiledMap;
|
||||
|
||||
NS_CC_END
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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_ {
|
||||
|
@ -125,6 +127,35 @@ enum
|
|||
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:
|
||||
|
@ -185,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
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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>
|
Loading…
Reference in New Issue