From 500aa1e6e468a37914b7b647af5b50c8a93ca888 Mon Sep 17 00:00:00 2001 From: Miles Ward Date: Sat, 18 May 2024 11:56:23 -0700 Subject: [PATCH 1/2] Added offsets to SFMLOrthogonalLayer.hpp. Also, you may now press W to make the map "wiggle" --- SFMLExample/src/SFMLOrthogonalLayer.hpp | 7 +++++++ SFMLExample/src/main.cpp | 20 ++++++++++++++++++++ 2 files changed, 27 insertions(+) diff --git a/SFMLExample/src/SFMLOrthogonalLayer.hpp b/SFMLExample/src/SFMLOrthogonalLayer.hpp index 9bc41f8..0ac4505 100644 --- a/SFMLExample/src/SFMLOrthogonalLayer.hpp +++ b/SFMLExample/src/SFMLOrthogonalLayer.hpp @@ -34,6 +34,7 @@ are implemented. #ifndef SFML_ORTHO_HPP_ #define SFML_ORTHO_HPP_ +#include #include #include #include @@ -125,6 +126,9 @@ class MapLayer final : public sf::Drawable const auto& selectedChunk = getChunkAndTransform(tileX, tileY, chunkLocale); return selectedChunk->getColor(chunkLocale.x, chunkLocale.y); } + + void setOffset(sf::Vector2f offset) { this->offset = offset; } + sf::Vector2f getOffset() { return this->offset; } void update(sf::Time elapsed) { @@ -159,6 +163,7 @@ class MapLayer final : public sf::Drawable private: //increasing m_chunkSize by 4; fixes render problems when mapsize != chunksize //sf::Vector2f m_chunkSize = sf::Vector2f(1024.f, 1024.f); + sf::Vector2f offset = sf::Vector2f(0, 0); sf::Vector2f m_chunkSize = sf::Vector2f(512.f, 512.f); sf::Vector2u m_chunkCount; sf::Vector2u m_MapTileSize; // general Tilesize of Map @@ -599,8 +604,10 @@ class MapLayer final : public sf::Drawable std::swap(m_visibleChunks, visible); } + void draw(sf::RenderTarget& rt, sf::RenderStates states) const override { + states.transform.translate(offset); //calc view coverage and draw nearest chunks updateVisibility(rt.getView()); for (const auto& c : m_visibleChunks) diff --git a/SFMLExample/src/main.cpp b/SFMLExample/src/main.cpp index 4f80226..81dab0d 100644 --- a/SFMLExample/src/main.cpp +++ b/SFMLExample/src/main.cpp @@ -26,8 +26,10 @@ source distribution. *********************************************************************/ #include +#include #include +#include #include #include "SFMLOrthogonalLayer.hpp" @@ -44,6 +46,8 @@ int main() MapLayer layerTwo(map, 2); sf::Clock globalClock; + sf::Clock wiggleClock; + bool doWiggle = false; while (window.isOpen()) { sf::Event event; @@ -51,10 +55,26 @@ int main() { if (event.type == sf::Event::Closed) window.close(); + if( event.type == sf::Event::KeyPressed ) { + switch(event.key.code) { + case sf::Keyboard::W: + /// toggle doWiggle + doWiggle = !doWiggle; + break; + } + } } + sf::Time duration = globalClock.restart(); layerZero.update(duration); + sf::Vector2f newOffset = sf::Vector2f(0.f, 0.f); + if( doWiggle ) { + newOffset = sf::Vector2f(cosf(wiggleClock.getElapsedTime().asSeconds())*100.f, 0.f); + } + layerZero.setOffset(newOffset); + layerOne.setOffset(newOffset); + layerTwo.setOffset(newOffset); window.clear(sf::Color::Black); window.draw(layerZero); From c15167aa17473d244845126fb5cee29742f412d5 Mon Sep 17 00:00:00 2001 From: fallahn Date: Sun, 19 May 2024 11:34:31 +0100 Subject: [PATCH 2/2] code consistency and warnings fixes --- SFMLExample/src/SFMLOrthogonalLayer.hpp | 114 +++++++++++++++--------- SFMLExample/src/main.cpp | 28 +++--- tmxlite.sln | 2 +- 3 files changed, 90 insertions(+), 54 deletions(-) diff --git a/SFMLExample/src/SFMLOrthogonalLayer.hpp b/SFMLExample/src/SFMLOrthogonalLayer.hpp index 0ac4505..10b5687 100644 --- a/SFMLExample/src/SFMLOrthogonalLayer.hpp +++ b/SFMLExample/src/SFMLOrthogonalLayer.hpp @@ -1,5 +1,5 @@ /********************************************************************* -(c) Matt Marchant & contributors 2016 - 2019 +(c) Matt Marchant & contributors 2016 - 2024 http://trederia.blogspot.com tmxlite - Zlib license. @@ -34,7 +34,6 @@ are implemented. #ifndef SFML_ORTHO_HPP_ #define SFML_ORTHO_HPP_ -#include #include #include #include @@ -46,6 +45,7 @@ are implemented. #include #include #include +#include #include #include @@ -83,8 +83,8 @@ class MapLayer final : public sf::Drawable const auto tileSize = map.getTileSize(); m_chunkSize.x = std::floor(m_chunkSize.x / tileSize.x) * tileSize.x; m_chunkSize.y = std::floor(m_chunkSize.y / tileSize.y) * tileSize.y; - m_MapTileSize.x = map.getTileSize().x; - m_MapTileSize.y = map.getTileSize().y; + m_mapTileSize.x = map.getTileSize().x; + m_mapTileSize.y = map.getTileSize().y; const auto& layer = layers[idx]->getLayerAs(); createChunks(map, layer); @@ -100,35 +100,35 @@ class MapLayer final : public sf::Drawable const sf::FloatRect& getGlobalBounds() const { return m_globalBounds; } - void setTile(int tileX, int tileY, tmx::TileLayer::Tile tile, bool refresh = true) + void setTile(std::int32_t tileX, std::int32_t tileY, tmx::TileLayer::Tile tile, bool refresh = true) { sf::Vector2u chunkLocale; const auto& selectedChunk = getChunkAndTransform(tileX, tileY, chunkLocale); selectedChunk->setTile(chunkLocale.x, chunkLocale.y, tile, refresh); } - tmx::TileLayer::Tile getTile(int tileX, int tileY) + tmx::TileLayer::Tile getTile(std::int32_t tileX, std::int32_t tileY) { sf::Vector2u chunkLocale; const auto& selectedChunk = getChunkAndTransform(tileX, tileY, chunkLocale); return selectedChunk->getTile(chunkLocale.x, chunkLocale.y); } - void setColor(int tileX, int tileY, sf::Color color, bool refresh = true) + void setColor(std::int32_t tileX, std::int32_t tileY, sf::Color color, bool refresh = true) { sf::Vector2u chunkLocale; const auto& selectedChunk = getChunkAndTransform(tileX, tileY, chunkLocale); selectedChunk->setColor(chunkLocale.x, chunkLocale.y, color, refresh); } - sf::Color getColor(int tileX, int tileY) + sf::Color getColor(std::int32_t tileX, std::int32_t tileY) { sf::Vector2u chunkLocale; const auto& selectedChunk = getChunkAndTransform(tileX, tileY, chunkLocale); return selectedChunk->getColor(chunkLocale.x, chunkLocale.y); } - void setOffset(sf::Vector2f offset) { this->offset = offset; } - sf::Vector2f getOffset() { return this->offset; } + void setOffset(sf::Vector2f offset) { m_offset = offset; } + sf::Vector2f getOffset() const { return m_offset; } void update(sf::Time elapsed) { @@ -163,11 +163,11 @@ class MapLayer final : public sf::Drawable private: //increasing m_chunkSize by 4; fixes render problems when mapsize != chunksize //sf::Vector2f m_chunkSize = sf::Vector2f(1024.f, 1024.f); - sf::Vector2f offset = sf::Vector2f(0, 0); sf::Vector2f m_chunkSize = sf::Vector2f(512.f, 512.f); sf::Vector2u m_chunkCount; - sf::Vector2u m_MapTileSize; // general Tilesize of Map + sf::Vector2u m_mapTileSize; // general Tilesize of Map sf::FloatRect m_globalBounds; + sf::Vector2f m_offset; using TextureResource = std::map>; TextureResource m_textureResource; @@ -185,20 +185,23 @@ class MapLayer final : public sf::Drawable { public: using Ptr = std::unique_ptr; - using Tile = std::array; - Chunk(const tmx::TileLayer& layer, std::vector tilesets, - const sf::Vector2f& position, const sf::Vector2f& tileCount, const sf::Vector2u& tileSize, - std::size_t rowSize, TextureResource& tr, const std::map& animTiles) + + Chunk(const tmx::TileLayer& layer, std::vector tilesets, + const sf::Vector2f& position, const sf::Vector2f& tileCount, + const sf::Vector2u& tileSize, std::size_t rowSize, + TextureResource& tr, const std::map& animTiles) : m_animTiles(animTiles) { setPosition(position); layerOpacity = static_cast(layer.getOpacity() / 1.f * 255.f); + sf::Color vertColour = sf::Color(200 ,200, 200, layerOpacity); auto offset = layer.getOffset(); layerOffset = { static_cast(offset.x), static_cast(offset.y) }; chunkTileCount = { tileCount.x, tileCount.y }; mapTileSize = tileSize; + const auto& tileIDs = layer.getTiles(); //go through the tiles and create all arrays (for latter manipulation) @@ -234,7 +237,7 @@ class MapLayer final : public sf::Drawable } for (const auto& ca : m_chunkArrays) { - sf::Uint32 idx = 0; + std::uint32_t idx = 0; std::uint32_t xPos = static_cast(getPosition().x / mapTileSize.x); std::uint32_t yPos = static_cast(getPosition().y / mapTileSize.y); for (auto y = yPos; y < yPos + chunkTileCount.y; ++y) @@ -256,17 +259,17 @@ class MapLayer final : public sf::Drawable sf::Vector2f tileOffset(static_cast(x) * mapTileSize.x, static_cast(y) * mapTileSize.y + mapTileSize.y - ca->tileSetSize.y); auto idIndex = m_chunkTileIDs[idx].ID - ca->m_firstGID; - sf::Vector2f tileIndex(idIndex % ca->tsTileCount.x, idIndex / ca->tsTileCount.x); + sf::Vector2f tileIndex(sf::Vector2i(idIndex % ca->tsTileCount.x, idIndex / ca->tsTileCount.x)); tileIndex.x *= ca->tileSetSize.x; tileIndex.y *= ca->tileSetSize.y; Tile tile = { sf::Vertex(tileOffset - getPosition(), m_chunkColors[idx], tileIndex), - sf::Vertex(tileOffset - getPosition() + sf::Vector2f(ca->tileSetSize.x, 0.f), m_chunkColors[idx], tileIndex + sf::Vector2f(ca->tileSetSize.x, 0.f)), - sf::Vertex(tileOffset - getPosition() + sf::Vector2f(ca->tileSetSize.x, ca->tileSetSize.y), m_chunkColors[idx], tileIndex + sf::Vector2f(ca->tileSetSize.x, ca->tileSetSize.y)), + sf::Vertex(tileOffset - getPosition() + sf::Vector2f(static_cast(ca->tileSetSize.x), 0.f), m_chunkColors[idx], tileIndex + sf::Vector2f(static_cast(ca->tileSetSize.x), 0.f)), + sf::Vertex(tileOffset - getPosition() + sf::Vector2f(sf::Vector2u(ca->tileSetSize.x, ca->tileSetSize.y)), m_chunkColors[idx], tileIndex + sf::Vector2f(sf::Vector2u(ca->tileSetSize.x, ca->tileSetSize.y))), sf::Vertex(tileOffset - getPosition(), m_chunkColors[idx], tileIndex), - sf::Vertex(tileOffset - getPosition() + sf::Vector2f(ca->tileSetSize.x, ca->tileSetSize.y), m_chunkColors[idx], tileIndex + sf::Vector2f(ca->tileSetSize.x, ca->tileSetSize.y)), - sf::Vertex(tileOffset - getPosition() + sf::Vector2f(0.f, ca->tileSetSize.y), m_chunkColors[idx], tileIndex + sf::Vector2f(0.f, ca->tileSetSize.y)) + sf::Vertex(tileOffset - getPosition() + sf::Vector2f(sf::Vector2u(ca->tileSetSize.x, ca->tileSetSize.y)), m_chunkColors[idx], tileIndex + sf::Vector2f(sf::Vector2u(ca->tileSetSize.x, ca->tileSetSize.y))), + sf::Vertex(tileOffset - getPosition() + sf::Vector2f(0.f,static_cast(ca->tileSetSize.y)), m_chunkColors[idx], tileIndex + sf::Vector2f(0.f, static_cast(ca->tileSetSize.y))) }; doFlips(m_chunkTileIDs[idx].flipFlags,&tile[0].texCoords,&tile[1].texCoords,&tile[2].texCoords,&tile[3].texCoords,&tile[4].texCoords,&tile[5].texCoords); ca->addTile(tile); @@ -279,25 +282,34 @@ class MapLayer final : public sf::Drawable ~Chunk() = default; Chunk(const Chunk&) = delete; Chunk& operator = (const Chunk&) = delete; - std::vector& getActiveAnimations() { return m_activeAnimations; } - tmx::TileLayer::Tile getTile(int x, int y) const + + std::vector& getActiveAnimations() + { + return m_activeAnimations; + } + + tmx::TileLayer::Tile getTile(std::int32_t x, std::int32_t y) const { return m_chunkTileIDs[calcIndexFrom(x,y)]; } - void setTile(int x, int y, tmx::TileLayer::Tile tile, bool refresh) + + void setTile(std::int32_t x, std::int32_t y, tmx::TileLayer::Tile tile, bool refresh) { m_chunkTileIDs[calcIndexFrom(x,y)] = tile; maybeRegenerate(refresh); } - sf::Color getColor(int x, int y) const + + sf::Color getColor(std::int32_t x, std::int32_t y) const { return m_chunkColors[calcIndexFrom(x,y)]; } - void setColor(int x, int y, sf::Color color, bool refresh) + + void setColor(std::int32_t x, std::int32_t y, sf::Color color, bool refresh) { m_chunkColors[calcIndexFrom(x,y)] = color; maybeRegenerate(refresh); } + void maybeRegenerate(bool refresh) { if (refresh) @@ -309,11 +321,16 @@ class MapLayer final : public sf::Drawable generateTiles(); } } - int calcIndexFrom(int x, int y) const + + std::int32_t calcIndexFrom(std::int32_t x, std::int32_t y) const { - return x + y * chunkTileCount.x; + return x + y * static_cast(chunkTileCount.x); + } + + bool empty() const + { + return m_chunkArrays.empty(); } - bool empty() const { return m_chunkArrays.empty(); } void flipY(sf::Vector2f* v0, sf::Vector2f* v1, sf::Vector2f* v2, sf::Vector2f* v3, sf::Vector2f* v4, sf::Vector2f* v5) { @@ -433,9 +450,11 @@ class MapLayer final : public sf::Drawable { public: using Ptr = std::unique_ptr; + tmx::Vector2u tileSetSize; sf::Vector2u tsTileCount; std::uint32_t m_firstGID, m_lastGID; + explicit ChunkArray(const sf::Texture& t, const tmx::Tileset& ts) : m_texture(t) { @@ -455,6 +474,7 @@ class MapLayer final : public sf::Drawable { m_vertices.clear(); } + void addTile(const Chunk::Tile& tile) { for (const auto& v : tile) @@ -462,7 +482,11 @@ class MapLayer final : public sf::Drawable m_vertices.push_back(v); } } - sf::Vector2u getTextureSize() const { return m_texture.getSize(); } + + sf::Vector2u getTextureSize() const + { + return m_texture.getSize(); + } private: const sf::Texture& m_texture; @@ -483,6 +507,7 @@ class MapLayer final : public sf::Drawable std::map m_animTiles; // animation catalogue std::vector m_activeAnimations; // Animations to be done in this chunk std::vector m_chunkArrays; + void draw(sf::RenderTarget& rt, sf::RenderStates states) const override { states.transform *= getTransform(); @@ -495,14 +520,16 @@ class MapLayer final : public sf::Drawable std::vector m_chunks; mutable std::vector m_visibleChunks; - Chunk::Ptr& getChunkAndTransform(int x, int y, sf::Vector2u& chunkRelative) + + Chunk::Ptr& getChunkAndTransform(std::int32_t x, std::int32_t y, sf::Vector2u& chunkRelative) { - uint32_t chunkX = floor((x * m_MapTileSize.x) / m_chunkSize.x); - uint32_t chunkY = floor((y * m_MapTileSize.y) / m_chunkSize.y); - chunkRelative.x = ((x * m_MapTileSize.x) - chunkX * m_chunkSize.x ) / m_MapTileSize.x ; - chunkRelative.y = ((y * m_MapTileSize.y) - chunkY * m_chunkSize.y ) / m_MapTileSize.y ; + std::uint32_t chunkX = (x * m_mapTileSize.x) / static_cast(m_chunkSize.x); + std::uint32_t chunkY = (y * m_mapTileSize.y) / static_cast(m_chunkSize.y); + chunkRelative.x = ((x * m_mapTileSize.x) - chunkX * static_cast(m_chunkSize.x)) / m_mapTileSize.x ; + chunkRelative.y = ((y * m_mapTileSize.y) - chunkY * static_cast(m_chunkSize.y)) / m_mapTileSize.y ; return m_chunks[chunkX + chunkY * m_chunkCount.x]; } + void createChunks(const tmx::Map& map, const tmx::TileLayer& layer) { //look up all the tile sets and load the textures @@ -529,7 +556,7 @@ class MapLayer final : public sf::Drawable for (const auto& ts : usedTileSets) { const auto& path = ts->getImagePath(); - //std::unique_ptr newTexture = std::make_unique(); + std::unique_ptr newTexture = std::make_unique(); sf::Image img; if (!img.loadFromFile(path)) @@ -583,17 +610,17 @@ class MapLayer final : public sf::Drawable sf::Vector2f viewCorner = view.getCenter(); viewCorner -= view.getSize() / 2.f; - int posX = static_cast(std::floor(viewCorner.x / m_chunkSize.x)); - int posY = static_cast(std::floor(viewCorner.y / m_chunkSize.y)); - int posX2 = static_cast(std::ceil((viewCorner.x + view.getSize().x) / m_chunkSize.x)); - int posY2 = static_cast(std::ceil((viewCorner.y + view.getSize().x)/ m_chunkSize.y)); + std::int32_t posX = static_cast(std::floor(viewCorner.x / m_chunkSize.x)); + std::int32_t posY = static_cast(std::floor(viewCorner.y / m_chunkSize.y)); + std::int32_t posX2 = static_cast(std::ceil((viewCorner.x + view.getSize().x) / m_chunkSize.x)); + std::int32_t posY2 = static_cast(std::ceil((viewCorner.y + view.getSize().x)/ m_chunkSize.y)); std::vector visible; for (auto y = posY; y < posY2; ++y) { for (auto x = posX; x < posX2; ++x) { - std::size_t idx = y * int(m_chunkCount.x) + x; + std::size_t idx = y * std::int32_t(m_chunkCount.x) + x; if (idx >= 0u && idx < m_chunks.size() && !m_chunks[idx]->empty()) { visible.push_back(m_chunks[idx].get()); @@ -607,7 +634,8 @@ class MapLayer final : public sf::Drawable void draw(sf::RenderTarget& rt, sf::RenderStates states) const override { - states.transform.translate(offset); + states.transform.translate(m_offset); + //calc view coverage and draw nearest chunks updateVisibility(rt.getView()); for (const auto& c : m_visibleChunks) diff --git a/SFMLExample/src/main.cpp b/SFMLExample/src/main.cpp index 81dab0d..2c66d18 100644 --- a/SFMLExample/src/main.cpp +++ b/SFMLExample/src/main.cpp @@ -1,5 +1,5 @@ /********************************************************************* -(c) Matt Marchant & contributors 2016 - 2019 +(c) Matt Marchant & contributors 2016 - 2024 http://trederia.blogspot.com tmxlite - Zlib license. @@ -25,14 +25,13 @@ and must not be misrepresented as being the original software. source distribution. *********************************************************************/ + +#include "SFMLOrthogonalLayer.hpp" + #include -#include #include - #include -#include -#include "SFMLOrthogonalLayer.hpp" int main() { @@ -47,18 +46,25 @@ int main() sf::Clock globalClock; sf::Clock wiggleClock; + bool doWiggle = false; + while (window.isOpen()) { sf::Event event; while (window.pollEvent(event)) { if (event.type == sf::Event::Closed) + { window.close(); - if( event.type == sf::Event::KeyPressed ) { - switch(event.key.code) { + } + + else if( event.type == sf::Event::KeyPressed ) + { + switch(event.key.code) + { case sf::Keyboard::W: - /// toggle doWiggle + // toggle doWiggle doWiggle = !doWiggle; break; } @@ -68,9 +74,11 @@ int main() sf::Time duration = globalClock.restart(); layerZero.update(duration); + sf::Vector2f newOffset = sf::Vector2f(0.f, 0.f); - if( doWiggle ) { - newOffset = sf::Vector2f(cosf(wiggleClock.getElapsedTime().asSeconds())*100.f, 0.f); + if (doWiggle) + { + newOffset = sf::Vector2f(std::cos(wiggleClock.getElapsedTime().asSeconds()) * 100.f, 0.f); } layerZero.setOffset(newOffset); layerOne.setOffset(newOffset); diff --git a/tmxlite.sln b/tmxlite.sln index 35c67c5..a2d0e4b 100644 --- a/tmxlite.sln +++ b/tmxlite.sln @@ -71,6 +71,7 @@ Global {2298A657-D09A-438E-B976-5EE827966124}.Debug|ARM.ActiveCfg = Debug|Win32 {2298A657-D09A-438E-B976-5EE827966124}.Debug|ARM64.ActiveCfg = Debug|Win32 {2298A657-D09A-438E-B976-5EE827966124}.Debug|x64.ActiveCfg = Debug|x64 + {2298A657-D09A-438E-B976-5EE827966124}.Debug|x64.Build.0 = Debug|x64 {2298A657-D09A-438E-B976-5EE827966124}.Debug|x86.ActiveCfg = Debug|Win32 {2298A657-D09A-438E-B976-5EE827966124}.Debug|x86.Build.0 = Debug|Win32 {2298A657-D09A-438E-B976-5EE827966124}.Release|ARM.ActiveCfg = Release|Win32 @@ -83,7 +84,6 @@ Global {70A3EB5D-CEB9-4353-9964-7023B6C07A44}.Debug|ARM64.ActiveCfg = Debug|x64 {70A3EB5D-CEB9-4353-9964-7023B6C07A44}.Debug|ARM64.Build.0 = Debug|x64 {70A3EB5D-CEB9-4353-9964-7023B6C07A44}.Debug|x64.ActiveCfg = Debug|x64 - {70A3EB5D-CEB9-4353-9964-7023B6C07A44}.Debug|x64.Build.0 = Debug|x64 {70A3EB5D-CEB9-4353-9964-7023B6C07A44}.Debug|x86.ActiveCfg = Debug|Win32 {70A3EB5D-CEB9-4353-9964-7023B6C07A44}.Debug|x86.Build.0 = Debug|Win32 {70A3EB5D-CEB9-4353-9964-7023B6C07A44}.Release|ARM.ActiveCfg = Release|x64