mirror of https://github.com/axmolengine/axmol.git
[BUG] TileMap flipped/rotated animated tiles incorrect rendering. (#1098)
* Add test cases * Delete default_hrtf.txt * Fix rotated/flipped animated tile maps * Optimize bitwise operations * improve bitwise operations
This commit is contained in:
parent
8d52ad2e56
commit
969c2257f8
|
@ -356,7 +356,12 @@ void FastTMXLayer::setupTiles()
|
|||
}
|
||||
|
||||
int pos = static_cast<int>(newX + _layerSize.width * y);
|
||||
int gid = _tiles[pos];
|
||||
uint32_t gid = _tiles[pos];
|
||||
uint32_t flags = 0;
|
||||
|
||||
// issue#1098 TileMap flipped/rotated animation bug.
|
||||
flags |= gid & kTMXFlipedAll;
|
||||
gid &= ~kTMXFlipedAll;
|
||||
|
||||
// gid are stored in little endian.
|
||||
// if host is big endian, then swap
|
||||
|
@ -369,7 +374,7 @@ void FastTMXLayer::setupTiles()
|
|||
{
|
||||
if (_tileSet->_animationInfo.find(gid) != _tileSet->_animationInfo.end())
|
||||
{
|
||||
_animTileCoord[gid].emplace_back(Vec2(newX, y));
|
||||
_animTileCoord[gid].emplace_back(TMXTileAnimFlag{Vec2(newX, y), flags});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -960,9 +965,9 @@ TMXTileAnimManager::TMXTileAnimManager(FastTMXLayer* layer)
|
|||
_layer = layer;
|
||||
for (const auto& p : *_layer->getAnimTileCoord())
|
||||
{
|
||||
for (auto&& tilePos : p.second)
|
||||
for (auto&& tile : p.second)
|
||||
{
|
||||
_tasks.pushBack(TMXTileAnimTask::create(_layer, _layer->getTileSet()->_animationInfo.at(p.first), tilePos));
|
||||
_tasks.pushBack(TMXTileAnimTask::create(_layer, _layer->getTileSet()->_animationInfo.at(p.first), tile._tilePos, tile._flag));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -996,12 +1001,13 @@ void TMXTileAnimManager::stopAll()
|
|||
}
|
||||
}
|
||||
|
||||
TMXTileAnimTask::TMXTileAnimTask(FastTMXLayer* layer, TMXTileAnimInfo* animation, const Vec2& tilePos)
|
||||
TMXTileAnimTask::TMXTileAnimTask(FastTMXLayer* layer, TMXTileAnimInfo* animation, const Vec2& tilePos, uint32_t flag)
|
||||
{
|
||||
_layer = layer;
|
||||
_animation = animation;
|
||||
_frameCount = static_cast<uint32_t>(_animation->_frames.size());
|
||||
_tilePosition = tilePos;
|
||||
_flag = flag;
|
||||
std::stringstream ss;
|
||||
ss << "TickAnimOnTilePos(" << _tilePosition.x << "," << _tilePosition.y << ")";
|
||||
_key = ss.str();
|
||||
|
@ -1028,13 +1034,13 @@ void TMXTileAnimTask::stop()
|
|||
|
||||
void TMXTileAnimTask::setCurrFrame()
|
||||
{
|
||||
_layer->setTileGID(_animation->_frames[_currentFrame]._tileID, _tilePosition);
|
||||
_layer->setTileGID(_animation->_frames[_currentFrame]._tileID, _tilePosition, (TMXTileFlags)_flag);
|
||||
_currentFrame = (_currentFrame + 1) % _frameCount;
|
||||
}
|
||||
|
||||
TMXTileAnimTask* TMXTileAnimTask::create(FastTMXLayer* layer, TMXTileAnimInfo* animation, const Vec2& tilePos)
|
||||
TMXTileAnimTask* TMXTileAnimTask::create(FastTMXLayer* layer, TMXTileAnimInfo* animation, const Vec2& tilePos, uint32_t flag)
|
||||
{
|
||||
TMXTileAnimTask* ret = new TMXTileAnimTask(layer, animation, tilePos);
|
||||
TMXTileAnimTask* ret = new TMXTileAnimTask(layer, animation, tilePos, flag);
|
||||
ret->autorelease();
|
||||
return ret;
|
||||
}
|
||||
|
|
|
@ -286,7 +286,7 @@ public:
|
|||
*
|
||||
* @return Map from gid of animated tile to its instance.
|
||||
*/
|
||||
const std::unordered_map<uint32_t, std::vector<Vec2>>* getAnimTileCoord() { return &_animTileCoord; }
|
||||
const std::unordered_map<uint32_t, std::vector<TMXTileAnimFlag>>* getAnimTileCoord() { return &_animTileCoord; }
|
||||
|
||||
bool hasTileAnimation() const { return !_animTileCoord.empty(); }
|
||||
|
||||
|
@ -341,7 +341,7 @@ protected:
|
|||
ValueMap _properties;
|
||||
|
||||
/** map from gid of animated tile to its instance. Also useful for optimization*/
|
||||
std::unordered_map<uint32_t, std::vector<Vec2>> _animTileCoord;
|
||||
std::unordered_map<uint32_t, std::vector<TMXTileAnimFlag>> _animTileCoord;
|
||||
/** pointer to the tile animation manager of this layer */
|
||||
TMXTileAnimManager* _tileAnimManager = nullptr;
|
||||
|
||||
|
@ -389,8 +389,8 @@ protected:
|
|||
class AX_DLL TMXTileAnimTask : public Ref
|
||||
{
|
||||
public:
|
||||
TMXTileAnimTask(FastTMXLayer* layer, TMXTileAnimInfo* animation, const Vec2& tilePos);
|
||||
static TMXTileAnimTask* create(FastTMXLayer* layer, TMXTileAnimInfo* animation, const Vec2& tilePos);
|
||||
TMXTileAnimTask(FastTMXLayer* layer, TMXTileAnimInfo* animation, const Vec2& tilePos, uint32_t flag = 0);
|
||||
static TMXTileAnimTask* create(FastTMXLayer* layer, TMXTileAnimInfo* animation, const Vec2& tilePos, uint32_t flag = 0);
|
||||
/** start the animation task */
|
||||
void start();
|
||||
/** stop the animation task */
|
||||
|
@ -398,6 +398,9 @@ public:
|
|||
bool isRunning() const { return _isRunning; }
|
||||
|
||||
protected:
|
||||
/** tile flag */
|
||||
uint32_t _flag = 0;
|
||||
|
||||
/** set texture of tile to current frame */
|
||||
void setCurrFrame();
|
||||
/** tick to next frame and schedule next tick */
|
||||
|
|
|
@ -143,6 +143,17 @@ struct AX_DLL TMXTileAnimFrame
|
|||
float _duration = 0.0f;
|
||||
};
|
||||
|
||||
/** @brief TMXTileAnimFlag contains animated tile position and flag
|
||||
This information is obtained from the TMX file.
|
||||
*/
|
||||
struct AX_DLL TMXTileAnimFlag
|
||||
{
|
||||
/** position of tile */
|
||||
ax::Vec2 _tilePos;
|
||||
/** flag of a tile */
|
||||
uint32_t _flag = 0;
|
||||
};
|
||||
|
||||
/** @brief TMXTileAnimInfo contains the information about the animated tile like:
|
||||
- Animated Tile gid
|
||||
- frames the animated tile contains
|
||||
|
|
|
@ -67,6 +67,7 @@ FastTileMapTests::FastTileMapTests()
|
|||
ADD_TEST_CASE(TMXBug787New);
|
||||
ADD_TEST_CASE(TMXGIDObjectsTestNew);
|
||||
ADD_TEST_CASE(TileAnimTestNew);
|
||||
ADD_TEST_CASE(TileAnimTestNew2);
|
||||
}
|
||||
|
||||
TileDemoNew::TileDemoNew()
|
||||
|
@ -1398,3 +1399,35 @@ void TileAnimTestNew::onTouchBegan(const std::vector<ax::Touch*>& touches, ax::E
|
|||
_animStarted = !_animStarted;
|
||||
map->setTileAnimEnabled(_animStarted);
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------
|
||||
//
|
||||
// TileAnimTestNew2
|
||||
//
|
||||
//------------------------------------------------------------------
|
||||
TileAnimTestNew2::TileAnimTestNew2()
|
||||
{
|
||||
|
||||
map = FastTMXTiledMap::create("TileMaps/tile_animation_test_2.tmx");
|
||||
addChild(map, 0, kTagTileMap);
|
||||
|
||||
auto listener = EventListenerTouchAllAtOnce::create();
|
||||
listener->onTouchesBegan = AX_CALLBACK_2(TileAnimTestNew2::onTouchBegan, this);
|
||||
_eventDispatcher->addEventListenerWithSceneGraphPriority(listener, this);
|
||||
|
||||
Size AX_UNUSED s = map->getContentSize();
|
||||
AXLOG("ContentSize: %f, %f", s.width, s.height);
|
||||
|
||||
map->setTileAnimEnabled(_animStarted);
|
||||
}
|
||||
|
||||
std::string TileAnimTestNew2::title() const
|
||||
{
|
||||
return "Tile animation test with flipped/rotated. Click to toggle the animation";
|
||||
}
|
||||
|
||||
void TileAnimTestNew2::onTouchBegan(const std::vector<ax::Touch*>& touches, ax::Event* event)
|
||||
{
|
||||
_animStarted = !_animStarted;
|
||||
map->setTileAnimEnabled(_animStarted);
|
||||
}
|
||||
|
|
|
@ -351,4 +351,16 @@ public:
|
|||
void onTouchBegan(const std::vector<ax::Touch*>& touches, ax::Event* event);
|
||||
};
|
||||
|
||||
class TileAnimTestNew2 : public TileDemoNew
|
||||
{
|
||||
public:
|
||||
CREATE_FUNC(TileAnimTestNew2);
|
||||
TileAnimTestNew2();
|
||||
virtual std::string title() const override;
|
||||
|
||||
ax::FastTMXTiledMap* map;
|
||||
bool _animStarted = true;
|
||||
void onTouchBegan(const std::vector<ax::Touch*>& touches, ax::Event* event);
|
||||
};
|
||||
|
||||
#endif
|
||||
|
|
Loading…
Reference in New Issue