Welcome, Guest. Please login or register. Did you miss your activation email?

Show Posts

This section allows you to view all posts made by this member. Note that you can only see posts made in areas you currently have access to.


Messages - SuckyNoob

Pages: [1]
1
General / ISOMETRIC orientation in TMXLite for Tiled?
« on: June 08, 2017, 06:19:49 am »
This is mainly a question for anyone who has used TMXLITE.
https://github.com/fallahn/tmxlite/

Alright so I decided to use the tmxlite instead of the deprecated tmxloader.

I was playing around with the SFML example that comes with it, though it is only Orthographic.

https://github.com/fallahn/tmxlite/blob/master/SFMLExample/src/SFMLOrthogonalLayer.hpp

/*********************************************************************
Matt Marchant 2016
http://trederia.blogspot.com
tmxlite - Zlib license.
This software is provided 'as-is', without any express or
implied warranty. In no event will the authors be held
liable for any damages arising from the use of this software.
Permission is granted to anyone to use this software for any purpose,
including commercial applications, and to alter it and redistribute
it freely, subject to the following restrictions:
1. The origin of this software must not be misrepresented;
you must not claim that you wrote the original software.
If you use this software in a product, an acknowledgment
in the product documentation would be appreciated but
is not required.
2. Altered source versions must be plainly marked as such,
and must not be misrepresented as being the original software.
3. This notice may not be removed or altered from any
source distribution.
*********************************************************************/


/*
Creates an SFML drawable from an Orthogonal tmx map layer.
This is an example of drawing with SFML - not all features,
such as tile flipping, are implemented. For a more detailed
implementation, including artifact prevention, see:
https://github.com/fallahn/xygine/blob/master/xygine/src/components/ComponentTileMapLayer.cpp
*/


#ifndef SFML_ORTHO_HPP_
#define SFML_ORTHO_HPP_

#include <tmxlite/Map.hpp>
#include <tmxlite/TileLayer.hpp>

#include <SFML/Graphics/Drawable.hpp>
#include <SFML/Graphics/RenderStates.hpp>
#include <SFML/Graphics/RenderTarget.hpp>
#include <SFML/Graphics/Vertex.hpp>
#include <SFML/Graphics/Texture.hpp>
#include <SFML/Graphics/Transformable.hpp>

#include <memory>
#include <vector>
#include <array>
#include <map>
#include <string>
#include <limits>
#include <iostream>
#include <cmath>

class MapLayer final : public sf::Drawable
{
public:


    MapLayer(const tmx::Map& map, std::size_t idx)
    {
        const auto& layers = map.getLayers();
        if (map.getOrientation() == tmx::Orientation::Orthogonal &&
            idx < layers.size() && layers[idx]->getType() == tmx::Layer::Type::Tile)
        {
            //round the chunk size to the nearest tile
            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;

            const auto& layer = *dynamic_cast<const tmx::TileLayer*>(layers[idx].get());
            createChunks(map, layer);

            auto mapSize = map.getBounds();
            m_globalBounds.width = mapSize.width;
            m_globalBounds.height = mapSize.height;
        }
        else
        {
            std::cout << "Not a valid othogonal layer, nothing will be drawn." << std::endl;
        }
    }

    ~MapLayer() = default;
    MapLayer(const MapLayer&) = delete;
    MapLayer& operator = (const MapLayer&) = delete;

    const sf::FloatRect& getGlobalBounds() const { return m_globalBounds; }

private:

    sf::Vector2f m_chunkSize = sf::Vector2f(1024.f, 1024.f);
    sf::Vector2u m_chunkCount;
    sf::FloatRect m_globalBounds;

    using TextureResource = std::map<std::string, std::unique_ptr<sf::Texture>>;
    TextureResource m_textureResource;

    class Chunk final : public sf::Transformable, public sf::Drawable
    {
    public:
        using Ptr = std::unique_ptr<Chunk>;
        using Tile = std::array<sf::Vertex, 4u>;
        Chunk(const tmx::TileLayer& layer, std::vector<const tmx::Tileset*> tilesets,
            const sf::Vector2f& position, const sf::Vector2f& tileCount, std::size_t rowSize,  TextureResource& tr)
        {
            auto opacity = static_cast<sf::Uint8>(layer.getOpacity() /  1.f * 255.f);
            sf::Color vertColour = sf::Color::White;
            vertColour.a = opacity;

            auto offset = layer.getOffset();
            sf::Vector2f layerOffset(offset.x, offset.y);

            const auto& tileIDs = layer.getTiles();
           
            //go through the tiles and create the appropriate arrays
            for (const auto ts : tilesets)
            {
                bool chunkArrayCreated = false;
                auto tileSize = ts->getTileSize();

                sf::Vector2u tsTileCount;

                std::size_t xPos = static_cast<std::size_t>(position.x / tileSize.x);
                std::size_t yPos = static_cast<std::size_t>(position.y / tileSize.y);

                for (auto y = yPos; y < yPos + tileCount.y; ++y)
                {
                    for (auto x = xPos; x < xPos + tileCount.x; ++x)
                    {
                        auto idx = (y * rowSize + x);
                        if (idx < tileIDs.size() && tileIDs[idx].ID >= ts->getFirstGID()
                            && tileIDs[idx].ID < (ts->getFirstGID() + ts->getTileCount()))
                        {
                            //ID must belong to this set - so add a tile
                            if (!chunkArrayCreated)
                            {
                                m_chunkArrays.emplace_back(std::make_unique<ChunkArray>(*tr.find(ts->getImagePath())->second));
                                auto texSize = m_chunkArrays.back()->getTextureSize();
                                tsTileCount.x = texSize.x / tileSize.x;
                                tsTileCount.y = texSize.y / tileSize.y;
                                chunkArrayCreated = true;
                            }
                            auto& ca = m_chunkArrays.back();
                            sf::Vector2f tileOffset(x * tileSize.x, y * tileSize.y);
                           
                            auto idIndex = tileIDs[idx].ID - ts->getFirstGID();
                            sf::Vector2f tileIndex(idIndex % tsTileCount.x, idIndex / tsTileCount.x);
                            tileIndex.x *= tileSize.x;
                            tileIndex.y *= tileSize.y;
                            Tile tile =
                            {
                                sf::Vertex(tileOffset, vertColour, tileIndex),
                                sf::Vertex(tileOffset + sf::Vector2f(tileSize.x, 0.f), vertColour, tileIndex + sf::Vector2f(tileSize.x, 0.f)),
                                sf::Vertex(tileOffset + sf::Vector2f(tileSize.x, tileSize.y), vertColour, tileIndex + sf::Vector2f(tileSize.x, tileSize.y)),
                                sf::Vertex(tileOffset + sf::Vector2f(0.f, tileSize.y), vertColour, tileIndex + sf::Vector2f(0.f, tileSize.y))
                            };
                            ca->addTile(tile);
                        }
                    }
                }
            }
           
            setPosition(position);
        }
        ~Chunk() = default;
        Chunk(const Chunk&) = delete;
        Chunk& operator = (const Chunk&) = delete;

        bool empty() const { return m_chunkArrays.empty(); }
    private:
        class ChunkArray final : public sf::Drawable
        {
        public:
            using Ptr = std::unique_ptr<ChunkArray>;
            explicit ChunkArray(const sf::Texture& t)
                : m_texture(t) {}
            ~ChunkArray() = default;
            ChunkArray(const ChunkArray&) = delete;
            ChunkArray& operator = (const ChunkArray&) = delete;

            void addTile(const Chunk::Tile& tile)
            {
                for (const auto& v : tile)
                {
                    m_vertices.push_back(v);
                }
            }
            sf::Vector2u getTextureSize() const { return m_texture.getSize(); }

        private:
            const sf::Texture& m_texture;
            std::vector<sf::Vertex> m_vertices;
            void draw(sf::RenderTarget& rt, sf::RenderStates states) const override
            {
                states.texture = &m_texture;
                rt.draw(m_vertices.data(), m_vertices.size(), sf::Quads, states);
            }
        };

        std::vector<ChunkArray::Ptr> m_chunkArrays;
        void draw(sf::RenderTarget& rt, sf::RenderStates states) const override
        {
            states.transform *= getTransform();
            for (const auto& a : m_chunkArrays)
            {
                rt.draw(*a, states);
            }
        }
    };

    std::vector<Chunk::Ptr> m_chunks;
    mutable std::vector<const Chunk*> m_visibleChunks;
    void createChunks(const tmx::Map& map, const tmx::TileLayer& layer)
    {
        //look up all the tile sets and load the textures
        const auto& tileSets = map.getTilesets();
        const auto& layerIDs = layer.getTiles();
        std::uint32_t maxID = std::numeric_limits<std::uint32_t>::max();
        std::vector<const tmx::Tileset*> usedTileSets;

        for (auto i = tileSets.rbegin(); i != tileSets.rend(); ++i)
        {
            for (const auto& tile : layerIDs)
            {
                if (tile.ID >= i->getFirstGID() && tile.ID < maxID)
                {
                    usedTileSets.push_back(&(*i));
                    break;
                }
            }
            maxID = i->getFirstGID();
        }

        sf::Image fallback;
        fallback.create(2, 2, sf::Color::Magenta);
        for (const auto ts : usedTileSets)
        {
            const auto& path = ts->getImagePath();
            std::unique_ptr<sf::Texture> newTexture = std::make_unique<sf::Texture>();
            sf::Image img;
            if (!img.loadFromFile(path))
            {
                newTexture->loadFromImage(fallback);
            }
            else
            {
                if (ts->hasTransparency())
                {
                    auto transparency = ts->getTransparencyColour();
                    img.createMaskFromColor({ transparency.r, transparency.g, transparency.b, transparency.a });
                }
                newTexture->loadFromImage(img);
            }
            m_textureResource.insert(std::make_pair(path, std::move(newTexture)));
        }

        //calculate the number of chunks in the layer
        //and create each one
        const auto bounds = map.getBounds();
        m_chunkCount.x = static_cast<sf::Uint32>(std::ceil(bounds.width / m_chunkSize.x));
        m_chunkCount.y = static_cast<sf::Uint32>(std::ceil(bounds.height / m_chunkSize.y));

        sf::Vector2f tileCount(m_chunkSize.x / map.getTileSize().x, m_chunkSize.y / map.getTileSize().y);

        for (auto y = 0u; y < m_chunkCount.y; ++y)
        {
            for (auto x = 0u; x < m_chunkCount.x; ++x)
            {
                m_chunks.emplace_back(std::make_unique<Chunk>(layer, usedTileSets,
                    sf::Vector2f(x * m_chunkSize.x, y * m_chunkSize.y), tileCount, map.getTileCount().x, m_textureResource));
            }
        }
    }

    void updateVisibility(const sf::View& view) const
    {
        sf::Vector2f viewCorner = view.getCenter();
        viewCorner -= view.getSize() / 2.f;
       
        int posX = static_cast<int>(std::floor(viewCorner.x / m_chunkSize.x));
        int posY = static_cast<int>(std::floor(viewCorner.y / m_chunkSize.y));

        std::vector<const Chunk*> visible;
        for (auto y = posY; y < posY + 2; ++y)
        {
            for (auto x = posX; x < posX + 2; ++x)
            {
                auto idx = y * int(m_chunkCount.x) + x;
                if (idx >= 0 && idx < m_chunks.size() && !m_chunks[idx]->empty())
                {
                    visible.push_back(m_chunks[idx].get());
                }
            }
        }

        std::swap(m_visibleChunks, visible);
    }

    void draw(sf::RenderTarget& rt, sf::RenderStates states) const override
    {
        //calc view coverage and draw nearest chunks
        updateVisibility(rt.getView());
        for (const auto& c : m_visibleChunks)
        {
            rt.draw(*c, states);
        }
    }
};

#endif //SFML_ORTHO_HPP_
 

Unfortunately I just looked and can't find the file with the changes I already made. I may have deleted it.

The following code is how I was making an isometric map before i started using Tiled and TMXLITE.

void Map::draw(sf::RenderWindow& window, float dt)
{
        for (uint y = 0; y < m_Height; ++y)
        {
                for (uint x = 0; x < m_Width; ++x)
                {
                        /* Set the position of the tile in the 2d world */
                        sf::Vector2f pos;
                        pos.x = (float)((x - y) * m_TileSize + m_Width * m_TileSize);
                        pos.y = (float)((x + y) * m_TileSize * 0.5);
                        m_Tiles[x + y * m_Width].m_Sprite.setPosition(pos);

                        /* Draw the tile */
                        m_Tiles[x + y * m_Width].Draw(window, dt);
                }
        }
}
 

I believe I had changed the tileSizes and the offset properly with that TMXLITE   "SFML Example", and it was creating the "chunks" it just wasn't creating them properly I don't think. Or it could have been the update visibility code. I'm not really sure what is all going on there.

If anyone could give me some tips on where in that TMXLITE SFML Example code I need to change the formulas that are currently drawing, or creating chunks in the array, and the update visibility Orthographic 1:1 ratio to my Isometric 2:1

Again this is really only if anyone has used TMXLite. And if you do and have a patreon or something, I am willing to pay for a tutorial, or pay for someone to create a loader that just does the isometric. I just need to get past this rendering and I can get on with making my game, lol.

Or if anyone knows of any reputable sites where I can post a project for freelancers that will do small projects for pay that would be awesome too.

Thanks for your time if you read this, and doubly if you responded!

2
General / Re: sfml-tmxloader for Tiled Map Editor?
« on: May 15, 2017, 08:41:05 pm »
Ya I would have posted the error logs. The thing is I don't even know if I set it up right in the first place. That tutorial is a bit confusing. It says at the top that it now supports creating shared libs and static libs. So should I ignore what comes after about zlib and is that out of date?

I used Cmake and could create the static libs. But I want the dlls. So far I could only create the pugi-d.dll and pugi.dll. It wont output tmxloader.dll(s).

If anyone reads this if they can give an exact runthrough/process of what I am supposed to do to get the libs/.dlls from Cmake so I can include them in my project that would be sweet.

At first I just tried to include the "include" directory like I did with the SFML library. But that gives me "unresolved externals". Now those are a different story. I understand what unresolved externals are. But can't find which externals those are, the debugger wont send me to the file the error gets thrown from when I double click the message.

I'll try again and when those error messages for unresolved externals pop back up I'll post them in here.

(I'd prefer to use the sfml-tmxloader instead of tmxlite, because it comes with an awesome quadtree! among other things) But I even tried tmxlite and I also can't get that to work. Nor the STP tmx loader

3
General / sfml-tmxloader for Tiled Map Editor?
« on: May 14, 2017, 11:03:04 pm »
Has anyone used it?

I downloaded the Library and can get it into my codebase to at least load a map file. Sort of. I get no error warnings until I try and build and then it throws all these errors talking about "8 unresolved externals"

It looks like they are unresolved externals pertaining to the sfml-tmxloader-master library.

I am confused.

This is the library.
https://github.com/fallahn/sfml-tmxloader

and this is a template for VS that uses it and SFML
https://github.com/MossFrog/Tile_Map

The template version doesn't throw any "unresolved externals"
Yet it has no more code (that needs to be used by the tmxloader lib) than my own project.....

Anyone have an idea of what's going on? Or can possibly point to a tutorial on how to use tmxloader or how to make a json map loader in C++ for SFML with the Tiled json/tmx exported files?

Pages: [1]
anything