Coder Social home page Coder Social logo

sfml-tmxloader's Introduction

NOTE: Development of this project is indefinitely suspended in favour of tmxlite which supports generic rendering across C++ frameworks such as SFML and SDL2, requires no external linkage and has broader platform support, including mobile devices.

Tiled tmx map loader for SFML 2.0.0

/*********************************************************************

Matt Marchant 2013 - 2016
SFML Tiled Map Loader - https://github.com/bjorn/tiled/wiki/TMX-Map-Format

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.

*********************************************************************/

This class is designed to load TILED .tmx format maps, compatible with
TILED up to version 0.9.0

http://trederia.blogspot.co.uk/2013/05/tiled-map-loader-for-sfml.html

What's Supported

Uses pugixml (included) to parse xml
Supports orthogonal maps
Supports isometric maps
Supports conversion between orthogonal and isometric world coords
Parses all types of layers (normal, object and image), layer properties
Parses all types of object, object shapes, types, properties
Option to draw debug output of objects and tile grid
Supports multiple tile sets, including tsx files and collections of images
Supports all layer encoding and compression: base64, csv, zlib, gzip and xml (requires zlib library, see /lib directory)
Quad tree partitioning / querying of map object data
Optional utility functions for converting tmx map objects into box2D body data

What's not supported / limitations

Parsing of individual tile properties
Staggered isometric maps

Requirements

pugixml (included)
zlib (http://zlib.net/)
SFML 2.x (http://sfml-dev.org)
Minimal C++11 compiler support (tested with VS11 and GCC4.7)

Usage

With the Cmake file provided create a project for the compiler of your choice to build and install the map loader as either a static or shared library. You can use cmake-gui (useful for windows users) to see all the options, such as building the example applications.

To quickly get up and running create an instance of the MapLoader class

tmx::MapLoader ml("path/to/maps");

load a map file

ml.load("map.tmx");

and draw it in your main loop

renderTarget.draw(ml);

Note that the constructor takes a path to the directory containing the map files as a parameter (with or without the trailing '/') so that you only need pass the map name to MapLoader::load(). If you have images and/or tileset data in another directory you may add it with:

ml.addSearchPath(path);

before attempting to load the map file.

New maps can be loaded simply by calling the load function again, existing maps will be automatically unloaded. MapLoader::load() also returns true on success and false on failure, to aid running the function in its own thread for example. Conversion functions are provided for converting coordinate spaces between orthogonal and isometric. For instance MapLoader::orthogonalToIsometric() will convert mouse coordinates from screen space:

0--------X
|
|
|
|
|
Y

to isometric space:

     0
    / \
   /   \
  /     \
 /       \
Y         X

Layer information can be accessed through MapLoader::getLayers()

bool collision;
const auto& layers = ml.getLayers();
for(const auto& layer : layers)
{
    if(layer.name == "Collision")
    {
        for(const auto& object : layer.objects)
        {
            collision = object.contains(point);
        }
    }
}

The quad tree is used to reduce the number of MapObjects used during a query. If a map contains hundreds of objects which are used for collision it makes little sense to test them all if only a few are ever within collision range. For example in your update loop first call:

ml.updateQuadTree(myRect);

where myRect is the area representing the root node. You will probably only want to start with MapObjects which are visible on screen, so set myRect to your view area. Then query the quad tree with another FloatRect representing the area for potential collision. This could be the bounding box of your sprite:

std::vector<MapObject*> objects = ml.queryQuadTree(mySprite.getGlobalBounds());

This returns a vector of pointers to MapObjects contained within any quads which are intersected by your sprite's bounds. You can then proceed to perform any collision testing as usual.

Some utility functions are providied in tmx2box2d.h/cpp. If you use box2d for physics then add these files to you project, or set the box2d option to true when configuring the cmake file. You may then create box2d physics bodies using the BodyCreator:

sf::Vector2u tileSize(16, 16);
b2Body* body = tmx::BodyCreator::add(mapObject, b2World, tileSize);

where b2World is a reference to a valid box2D physics world. The body creator is only a utility class, so it is no problem letting it go out of scope once your bodies are all created. As box2d uses a different coordinate system to SFML there are 4 functions for converting from one space to another:

    b2Vec2 sfToBoxVec(const sf::Vector2f& vec);
    sf::Vector2f boxToSfVec(const b2Vec2& vec);
    float sfToBoxFloat(float val);
    float boxToSfFloat(float val);

You should use these whenever you are trying to draw with SFML based on the physics output, or set box2d parameters in SFML world values. When using box2d you may find that the build types of both the map loader and box2d should match (ie both static or both shared libs).

Debugging output can be enabled with one of the following preprocessor directives:

#define LOG_OUTPUT_CONSOLE

all output is directed to the console window

#define LOG_OUTPUT_FILE

all output is written to a file named output.log in the executable directory

#define LOG_OUTPUT_ALL

log output is directed to both the console and output.log

Logging is disabled by default. The level of log information can be set with

tmx::setLogLevel()

by providing a bitmask for the level required. For instance to only log warnings and errors use:

tmx::setLogLevel(tmx::Logger::Warning | tmx::Logger::Error);

For more detailed examples see the source in the examples folder, and the wiki on github: https://github.com/fallahn/sfml-tmxloader/wiki

Doxygen documentation can also be generated with the doxy file in the docs folder.

sfml-tmxloader's People

Contributors

123marvin123 avatar dmitrumoth avatar docwild avatar expl0it3r avatar fallahn avatar muon avatar sundeepk avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

sfml-tmxloader's Issues

layer->tiles doesn't give tiles from layers

Hi, correct me if I'm wrong but shouldn't following code return back a vector containing the map tiles?
Or how can I get the information of the tiles in a layer from a map?

for (auto layer = map.GetLayers().begin(); layer != map.GetLayers().end(); ++layer)
{
    if (layer->name == "fooLayer")
    {
       tmx::MapTiles fooTiles = layer->tiles;
       std::cout << "FooTiles = " << fooTiles.size() << std::endl;
       // result is size = 0
    }
}

MapObject::Move is incorrect

moving the points as well as the centre point adds up to double the movement (the points are supposed to be relative)

Unresolved external symbol

Using Visual Studio 2015, I can include the file MapLoader.h and plugixml.h just fine, but after adding tmx::MapLoader ml("maps\\"); the compiler crashes with this error:
Error LNK2019 unresolved external symbol "public: __cdecl tmx::MapLoader::MapLoader(class std::basic_string<char,struct std::char_traits<char>,class std::allocator<char> > const &,unsigned char)" (??0MapLoader@tmx@@QEAA@AEBV?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@E@Z) referenced in function "void __cdecl 'dynamic initializer for 'ml''(void)" (??__Eml@@YAXXZ)
Not sure what I'm doing wrong or if it's a bug :/

Add debugging levels for console output

I've found the debug information useful at the beginning, when my objective was to develop a basic structure of the game and get the map to load, but now it's making the debugging process more difficult. I get about 400 lines per map load, which requires a lot of scrolling to get to the beginning.

My suggestion to improve this is to split the messages up into debug levels. The user can set the debug level using a static variable and only messages with an equal or higher score get shown.

Visual Studio Compatability issues

I'm having difficulty using your libraries with visual studio 2013, can you possibly add a tutorial to the description or a link on how to integrate your libraries to a visual studio project?

Best Regards.

Graphical issues when loading new map with different tile size

I've defined two maps, an exterior using 64x64 tiles, and an interior using 32x32 tiles.
Exterior:
exterior

Interior:
interior

My program begins in the interior, and if it detects a collision with a warp point, loads in the other map. Initially everything looks fine, but when the other map is loaded, it seems as though the tile sizes aren't updated in the loader object.

Transitioning from inside to out yields:
exterior_warped

Transitioning from outside to in yields:
interior_warped

Can't draw map properly if it wasn't the the first one the maploader loaded.

Huge apologies if this is me missing something obvious. I'm not sure if this is an issue or if I'm doing something wrong.

When I load a map in the program for the first time like ml.Load("first.tmx"); it loads the map and draws it fine. But later on in the program, when I load another map to the same maploader like ml.Load("second.tmx"); and draw it, it will only draw the first 10x10 tiles from the top left.
e.g. first load: http://i.imgur.com/mS6lR3t.png?1
second load: http://i.imgur.com/SDJ0Noo.png?1

I'm not doing anything with SFML's views and the map is the same size as the window. Thanks for any help.

Map is rendering one level high?

I seem to be having an issue with my rendering my map...

image

And yet within Tiled:

image

(It's hard to tell, but that vertical scroll bar is 'greyed out', as in you can't scroll up or down.) I can provide any code I'm using, my .tmx file, etc, just let me know what you need :)

VS2013 Project error not generate .libs

I selected in cmake shared libs dlls, at build the vs project, but at compile, the examples and drop an error of no find .lib files of tmx-loader or pugi (in release mode x32)

pugi.vcxproj -> E:\A\Software\C_C++\sfml-tmxloader-master\build\Release\pugi.dll
Error 2 error LNK1181: cannot open input file 'Release\pugi.lib' E:\A\Software\C_C++\sfml-tmxloader-master\build\LINK tmx-loader

Error 4 error LNK1181: cannot open input file 'Release\tmx-loader.lib' E:\A\Software\C_C++\sfml-tmxloader-master\build\LINK QuadTree

Doesn't work with SFML 2.2

Hello :)
I recently updated to SFML 2.2, but when I compiled my program to test it the map didn't show up. Si I tried with this minimal code:

#include <SFML/Graphics.hpp>
#include <tmx/MapLoader.h>

int main()
{
    sf::RenderWindow window(sf::VideoMode(640,480),"Test");
    tmx::MapLoader ml("assets");
    ml.Load("map.tmx");
    while(window.isOpen())
    {
        sf::Event event;
        while(window.pollEvent(event))
        {
            if(event.type == sf::Event::Closed) window.close();
        }
        window.clear();
        window.draw(ml);
        window.display();
    }

}

But that didn't work :/
I will try to download the 2.1 SFML (the changes don't really interests me), but it would be nice if for your library to be compatible with the new SFML :)

Errors : defined but not used

Here the build message : (I'm testing the example "Benchmark.cpp")

C:\ProjetsC++\TestTiled\include\TiledLoader\tmx\MapLoader.h|151|attention : 'std::string tmx::base64_decode(const string&)' declared 'static' but never defined [-Wunused-function]|
C:\ProjetsC++\TestTiled\include\TiledLoader\tmx..\Helpers.h|46|attention : 'const float Helpers::Vectors::GetLength(const Vector2f&)' defined but not used [-Wunused-function]|
C:\ProjetsC++\TestTiled\include\TiledLoader\tmx..\Helpers.h|68|attention : 'const float Helpers::Vectors::GetAngle(const Vector2f&)' defined but not used [-Wunused-function]|
C:\ProjetsC++\TestTiled\src\TiledLoader....\include\TiledLoader\tmx..\Helpers.h|46|attention : 'const float Helpers::Vectors::GetLength(const Vector2f&)' defined but not used [-Wunused-function]|
C:\ProjetsC++\TestTiled\src\TiledLoader....\include\TiledLoader\tmx..\Helpers.h|58|attention : 'const Vector2f Helpers::Vectors::Normalize(sf::Vector2f)' defined but not used [-Wunused-function]|
C:\ProjetsC++\TestTiled\src\TiledLoader....\include\TiledLoader\tmx..\Helpers.h|68|attention : 'const float Helpers::Vectors::GetAngle(const Vector2f&)' defined but not used [-Wunused-function]|
C:\ProjetsC++\TestTiled\src\TiledLoader....\include\TiledLoader\tmx\MapLoader.h||In constructor 'tmx::MapLoader::MapLoader(const string&)':|
C:\ProjetsC++\TestTiled\src\TiledLoader....\include\TiledLoader\tmx\MapLoader.h|111|attention : 'tmx::MapLoader::m_quadTreeAvailable' will be initialized after [-Wreorder]|
C:\ProjetsC++\TestTiled\src\TiledLoader....\include\TiledLoader\tmx\MapLoader.h|93|attention : 'std::string tmx::MapLoader::m_mapDirectory' [-Wreorder]|
C:\ProjetsC++\TestTiled\src\TiledLoader\MapLoaderPublic.cpp|35|attention : lorsqu'initialisé ici [-Wreorder]|
C:\ProjetsC++\TestTiled\src\TiledLoader....\include\TiledLoader\tmx\MapLoader.h|93|attention : 'tmx::MapLoader::m_mapDirectory' will be initialized after [-Wreorder]|
C:\ProjetsC++\TestTiled\src\TiledLoader....\include\TiledLoader\tmx\MapLoader.h|89|attention : 'float tmx::MapLoader::m_tileRatio' [-Wreorder]|
C:\ProjetsC++\TestTiled\src\TiledLoader\MapLoaderPublic.cpp|35|attention : lorsqu'initialisé ici [-Wreorder]|
C:\ProjetsC++\TestTiled\src\TiledLoader....\include\TiledLoader\tmx\MapLoader.h|151|attention : 'std::string tmx::base64_decode(const string&)' declared 'static' but never defined [-Wunused-function]|
C:\ProjetsC++\TestTiled\src\TiledLoader....\include\TiledLoader\tmx..\Helpers.h|46|attention : 'const float Helpers::Vectors::GetLength(const Vector2f&)' defined but not used [-Wunused-function]|
C:\ProjetsC++\TestTiled\src\TiledLoader....\include\TiledLoader\tmx..\Helpers.h|58|attention : 'const Vector2f Helpers::Vectors::Normalize(sf::Vector2f)' defined but not used [-Wunused-function]|
C:\ProjetsC++\TestTiled\src\TiledLoader....\include\TiledLoader\tmx..\Helpers.h|68|attention : 'const float Helpers::Vectors::GetAngle(const Vector2f&)' defined but not used [-Wunused-function]|
||=== Build finished: 16 errors, 0 warnings (0 minutes, 25 seconds) ===|

Please add functions to return map tiles' width and height

//returns tile width in pixels
sf::Uint16 GetTileWidth() const;
//returns tile height in pixels
sf::Uint16 GetTileHeight() const;

sf::Uint16 MapLoader::GetTileWidth() const
{
return m_tileWidth;
}

sf::Uint16 MapLoader::GetTileHeight() const
{
return m_tileHeight;
}

Optimise object layers which use tiles

Map objects can be drawn using tiles from tile sets. Currently these are drawn using an sf::Sprite to allow for easy transformation from information stored in the tmx file. This could be optimised with a vertex array to improve performance of layers with a lot of Tile type objects

GetLayers() doesn't work as spected

Hi!
I'm trying to render each layer individually. For so I made this little function:

tmx::MapLayer Map::GetLayer(std::string layerName){
    for( int num = 0; num < ml.GetLayers().size(); num++)
    {
        tmx::MapLayer res = tmx::MapLayer(ml.GetLayers().at(num));

        if(res.name == layerName)
        {
            return res;
        }
    }
    return tmx::MapLayer(ml.GetLayers().at(0));
}

So im calling it like this:

m->mWindow->draw(GetLayer("Capa 1"));

And the result is a little square at the top of the window
image

When the layer is much bigger

image

I don't know if GetLayers() is supposed to work like this or not. Maybe is a bug?

Thank you so much!

PS: Im using gcc 4.8 on Windows, if that helps...

BodyCreator::Add fix

Hello,
It seems that box2d uses pixels in 2BodyDef.position.Set() method and this is why BodyCreator is broken. Every created body is placed at 0,0 coords so i modified this code to this(only changed the position setting stuff and conversion methods):

//conversion methods
b2Vec2 tmx::SfToBoxVec(const sf::Vector2f& vec)
{
    return b2Vec2(vec.x,vec.y);
}

sf::Vector2f tmx::BoxToSfVec(const b2Vec2& vec)
{
    return sf::Vector2f(vec.x,vec.y);
}

float tmx::SfToBoxFloat(float val)
{
    return val * 0.02f;
}

float tmx::BoxToSfFloat(float val)
{
    return val * 50.0f;
}



b2Body* BodyCreator::Add(const MapObject& object, b2World& world, b2BodyType bodyType)
{
    assert(object.PolyPoints().size() > 1u);

    b2BodyDef bodyDef;
    bodyDef.type = bodyType;

    b2Body* body = nullptr;



    MapObjectShape shapeType = object.GetShapeType();
    sf::Uint16 pointCount = object.PolyPoints().size();

    if (shapeType == Polyline || pointCount < 3)
    {
        bodyDef.position.Set(object.GetPosition().x, object.GetPosition().y);
        body = world.CreateBody(&bodyDef);

        const Shape& shape = object.PolyPoints();
        b2FixtureDef f;
        f.density = 1.f;

        if (pointCount < 3)
        {
            bodyDef.position.Set(object.GetPosition().x, object.GetPosition().y);
            b2EdgeShape es;
            es.Set(SfToBoxVec(shape[0]), SfToBoxVec(shape[1]));
            f.shape = &es;
            body->CreateFixture(&f);
        }
        else
        {
            std::unique_ptr<b2Vec2[]> vertices(new b2Vec2[pointCount]);
            for (auto i = 0u; i < pointCount; i++)
                vertices[i] = SfToBoxVec(shape[i]);

            b2ChainShape cs;
            cs.CreateChain(vertices.get(), pointCount);
            f.shape = &cs;
            body->CreateFixture(&f);
        }
    }
    else if (shapeType == Circle ||
        (object.Convex() && pointCount <= b2_maxPolygonVertices))
    {
        b2FixtureDef f;
        f.density = 1.f;
        bodyDef.position = SfToBoxVec(object.GetCentre());
        if (shapeType == Circle)
        {
            //make a circle
            b2CircleShape c;
            c.m_radius = object.GetAABB().width / 2.f;
            f.shape = &c;

            body = world.CreateBody(&bodyDef);
            body->CreateFixture(&f);
        }
        else if (shapeType == Rectangle)
        {
            b2PolygonShape ps;
            ps.SetAsBox((object.GetAABB().width / 2.f), (object.GetAABB().height / 2.f));
            f.shape = &ps;

            body = world.CreateBody(&bodyDef);
            body->CreateFixture(&f);
        }
        else //simple convex polygon
        {
            bodyDef.position.Set(object.GetPosition().x, object.GetPosition().y);
            body = world.CreateBody(&bodyDef);

            const Shape& points = object.PolyPoints();
            m_CreateFixture(points, body);
        }
    }
    else //complex polygon
    {
        //break into smaller convex shapes
        bodyDef.position = SfToBoxVec(object.GetPosition());
        body = world.CreateBody(&bodyDef);

        m_Split(object, body);
    }

    return body;
}

It does work almost perfectly but there is still one little problem with it though.

Cmakelists line 129

there is a problem there, the previous cmakelists didn't cause any errors of this type, it is about pugi

Draw only visible tiles

In void LayerSet::draw(sf::RenderTarget& rt, sf::RenderStates states)
function draws every tile, even when it's not visible.
rt.draw(&m_vertices[0], static_cast<unsigned int>(m_vertices.size()), sf::Quads, states);
I know that sfml propably won't draw tiles which are outside of screen, but even looping through every tile in layer slows down application when using large tilemaps. For example in my project FPS drop about 30% (140 FPS when map is 50x50 and 100 FPS when 200x100). I use tiled layer for background. I know that framerate is low, but i also use some demanding shaders.

Since tiles are always in grid, it wouldn't be very hard to use that property and draw only visible tiles (especially when tiles would be stored in 2D array/vector).

Only first created layer get rendered

Hi, guys! Thanks for your work!

I started using your loader and faced an issue with rendering multiple layers.
Basically when i add more than one layer

screen shot 2015-11-12 at 12 14 30 pm

i see that sfml-txloader keeps rendering only one layer on scene:

screen shot 2015-11-12 at 12 18 00 pm

I compiled project with logging and log looks fine either:

INFO: Caching image files, please wait...
INFO: Processed isometric_grass_and_water.png
INFO: Processed castle1.png
INFO: Processed ground1.png
INFO: Processed ground2.png
INFO: Processed tree1.png
INFO: Processed tree2.png
INFO: Found standard map layer water
INFO: Found Base64 encoded layer data, decoding...
INFO: Found zlib compressed layer data, decompressing...
INFO: Found standard map layer ground
INFO: Found Base64 encoded layer data, decoding...
INFO: Found zlib compressed layer data, decompressing...
INFO: Found standard map layer building
INFO: Found Base64 encoded layer data, decoding...
INFO: Found zlib compressed layer data, decompressing...
INFO: Found standard map layer road
INFO: Found Base64 encoded layer data, decoding...
INFO: Found zlib compressed layer data, decompressing...
INFO: Found standard map layer tree
INFO: Found Base64 encoded layer data, decoding...
INFO: Found zlib compressed layer data, decompressing...
INFO: Parsed 5 layers.
INFO: Loaded tmx file successfully.

Could you please advice how to get all layers be rendered?

Thanks!

Non-contiguous tile IDs break rendering

If you have a collection of images as a tileset where you've deleted a tile from the middle, rendering breaks because sfml-tmxloader expects the IDs to be contiguous.

Terrain Tiled tmx load

Hello, thank you for your hard work. I Have been trying to load a map with Terrains but the loading always fail. Are terrain supported ? if yes I think it is a bug.

No compatibility with AnimatedSprite class?

Hi!
I'm new using TMXLoader, but what an incredible tool !
I'm also using AnimatedSprite class : https://github.com/SFML/SFML/wiki/Source%3A-AnimatedSprite
And here is the problem : Whenever I load a" tmx" map and more precisely whenever i draw it, I am no longer able to see my animated sprite on the screen, while in the meantime, I am able to see classics sprites...

Here's my code :

include <SFML/Graphics.hpp>

include <tmx/MapLoader.h>

include "AnimatedSprite.h"

include

int main()
{
// setup window
sf::Vector2i screenDimensions(800, 640);
sf::RenderWindow window(sf::VideoMode(screenDimensions.x, screenDimensions.y), "TMXLoader");
window.setFramerateLimit(60);
sf::View view(window.getDefaultView());

// load texture (spritesheet)
sf::Texture texture;
if (!texture.loadFromFile("ressource/character/walk.png"))
{
    std::cout << "Failed to load player spritesheet!" << std::endl;
    return 1;
}

// set up the animations for all four directions (set spritesheet and push frames)
Animation walkingAnimationUp;
walkingAnimationUp.setSpriteSheet(texture);

Animation walkingAnimationLeft;
walkingAnimationLeft.setSpriteSheet(texture);

Animation walkingAnimationDown;
walkingAnimationDown.setSpriteSheet(texture);

Animation walkingAnimationRight;
walkingAnimationRight.setSpriteSheet(texture);

for (int i = 0; i <= 512; i += 64)
{
    walkingAnimationUp.addFrame(sf::IntRect(i, 0, 64, 64));
    walkingAnimationLeft.addFrame(sf::IntRect(i, 64, 64, 64));
    walkingAnimationDown.addFrame(sf::IntRect(i, 128, 64, 64));
    walkingAnimationRight.addFrame(sf::IntRect(i, 192, 64, 64));
}

Animation* currentAnimation = &walkingAnimationDown;

// set up AnimatedSprite
AnimatedSprite animatedSprite(sf::seconds(0.2), true, false);
animatedSprite.setPosition(sf::Vector2f(screenDimensions / 2));

tmx::MapLoader ml("ressource/maps");
ml.Load("prison.tmx");

sf::Clock frameClock;

float speed = 100.f;
bool noKeyWasPressed = true;

while (window.isOpen())
{
    sf::Event event;
    while (window.pollEvent(event))
    {
        if (event.type == sf::Event::Closed)
            window.close();
        if (event.type == sf::Event::KeyPressed && event.key.code == sf::Keyboard::Escape)
            window.close();
    }

    sf::Time frameTime = frameClock.restart();

    // if a key was pressed set the correct animation and move correctly
    sf::Vector2f movement(0.f, 0.f);
    if (sf::Keyboard::isKeyPressed(sf::Keyboard::Up))
    {
        currentAnimation = &walkingAnimationUp;
        movement.y -= speed;
        noKeyWasPressed = false;
    }
    if (sf::Keyboard::isKeyPressed(sf::Keyboard::Down))
    {
        currentAnimation = &walkingAnimationDown;
        movement.y += speed;
        noKeyWasPressed = false;
    }
    if (sf::Keyboard::isKeyPressed(sf::Keyboard::Left))
    {
        currentAnimation = &walkingAnimationLeft;
        movement.x -= speed;
        noKeyWasPressed = false;
    }
    if (sf::Keyboard::isKeyPressed(sf::Keyboard::Right))
    {
        currentAnimation = &walkingAnimationRight;
        movement.x += speed;
        noKeyWasPressed = false;
    }
    animatedSprite.play(*currentAnimation);
    animatedSprite.move(movement * frameTime.asSeconds());

    // if no key was pressed stop the animation
    if (noKeyWasPressed)
    {
        animatedSprite.stop();
    }
    noKeyWasPressed = true;

    // update AnimatedSprite
    animatedSprite.update(frameTime);

    // draw
    window.clear();
    window.draw(animatedSprite);
    window.draw(ml);
    window.display();
}

return 0;

}

Building Error (SFML/Graphics/VertexArray.hpp not found)

Hello,

I'm trying to build sfml-tmxloader on Ubuntu 14.04. I pulled the source code from the git repository, created a build dir, set the SFML_ROOT to the path and ran "cmake ..". Here are the results:

-- Found SFML 2.1 in /home/hiram/Desenvolvimento/sfml/include
-- Found ZLIB: /usr/lib/x86_64-linux-gnu/libz.so (found version "1.2.8")
-- Found Box2D: /usr/lib/x86_64-linux-gnu/libBox2D.so
-- Configuring done
-- Generating done
-- Build files have been written to: /home/hiram/Desenvolvimento/sfml-tmxloader/build

Everything looks fine, but when I run "make" I get the following error message:

[ 14%] Building CXX object CMakeFiles/tmx-loader.dir/src/DebugShape.cpp.o
In file included from /home/hiram/Desenvolvimento/sfml-tmxloader/src/DebugShape.cpp:30:0:
/home/hiram/Desenvolvimento/sfml-tmxloader/include/tmx/DebugShape.h:33:41: fatal error: SFML/Graphics/VertexArray.hpp: Arquivo ou diretório não encontrado
#include <SFML/Graphics/VertexArray.hpp>
^
compilation terminated.
make[2]: ** [CMakeFiles/tmx-loader.dir/src/DebugShape.cpp.o] Erro 1
make[1]: ** [CMakeFiles/tmx-loader.dir/all] Erro 2
make: ** [all] Erro 2

It's basically saying that SFML/Graphics/VertexArray.hpp was not found (it's in portuguese), although CMake previously informed that it was able to find the SFML dir.

Any clues?

Thanks in advance.

proper parsing of tileset images

currently tileset images and tsx files are required to be in the same directory as the tmx map file. Paths should be properly parsed, both relatively and globally, so that images can be stored as the user requires. At the very least a proper descriptive error should be thrown when a path is not recognised.

[Question] Insert players in map and change its texture

Hi,

I am a student and this year we have to create a small video game in C ++. We decided to use some libraries to facilitate our work because we are beginner in C ++.

So, your librairy is very interesting but we didn't find the documentation and we have some basic questions (sorry if they are stupid :) ).

  1. How to insert the player in map between two layers to have a z-depth effect ? I tried to use a ImageLayer and modify its tile but it didn't work.
  2. When the player is inserted in the map, how to change its texture ?

Thank you and sorry for my bad english.

Laggy and doesn't draw all map?

I'm not sure why but the map is laggy and it only loads a portion of the map, here's my code:

#include "MapClass.h"

std::vector<sf::FloatRect> mapBounds;
tmx::MapLoader map("maps/");
std::vector<tmx::MapLayer> mapLayers;
sf::Vector2u mapSize;

MapClass::MapClass()
{
}

MapClass::~MapClass()
{
}

void MapClass::loadMap(std::string mapName, sf::RenderWindow &window)
{   
    map.Load(mapName);
    window.draw(map);
}

and I am drawing it like so in my main function:

map->loadMap("lvl1.tmx", window);

here is what it looks like when I run it

https://gyazo.com/79fe4505836707d4a15524f1ae30792a

Can't build with SFML 2.3.2

I'm not sure if its SFML 2.3.2 that's causing the problem but i get the following issues while trying to build:

17:15:47, /home/linde/repos/sfml-tmxloader, (master) > ls
cmake/  CMakeLists.txt*  examples/  fonts/  include/  lib/  maps/  packages/  README.md  src/
17:15:48, /home/linde/repos/sfml-tmxloader, (master) > mkdir build
17:15:52, /home/linde/repos/sfml-tmxloader, (master) > cd build/
17:15:53, /home/linde/repos/sfml-tmxloader/build, (master) > cmake ..
-- The C compiler identification is GNU 4.9.2
-- The CXX compiler identification is GNU 4.9.2
-- Check for working C compiler: /usr/bin/cc
-- Check for working C compiler: /usr/bin/cc -- works
-- Detecting C compiler ABI info
-- Detecting C compiler ABI info - done
-- Check for working CXX compiler: /usr/bin/c++
-- Check for working CXX compiler: /usr/bin/c++ -- works
-- Detecting CXX compiler ABI info
-- Detecting CXX compiler ABI info - done
-- Found SFML 2.3.2 in /usr/include
-- Found ZLIB: /usr/lib/x86_64-linux-gnu/libz.so (found version "1.2.8") 
-- Could NOT find Box2D (missing:  BOX2D_LIBRARIES BOX2D_INCLUDE_DIR) 

-> Box2D directories not found. Set BOX2D_INCLUDE_DIR to Box2D's include path and BOX2D_LIBRARIES to Box2D's lib directory path.
-> Make sure the Box2D libraries with the same configuration (Release/Debug, Static/Dynamic) exist.

-- Configuring done
-- Generating done
-- Build files have been written to: /home/linde/repos/sfml-tmxloader/build
17:15:55, /home/linde/repos/sfml-tmxloader/build, (master) > ls
CMakeCache.txt  CMakeFiles/  cmake_install.cmake  Makefile
17:15:56, /home/linde/repos/sfml-tmxloader/build, (master) > make
Scanning dependencies of target pugi
[  8%] Building CXX object CMakeFiles/pugi.dir/src/pugixml/pugixml.cpp.o
Linking CXX shared library libpugi.so
[  8%] Built target pugi
Scanning dependencies of target tmx-loader
[ 16%] Building CXX object CMakeFiles/tmx-loader.dir/src/DebugShape.cpp.o
[ 25%] Building CXX object CMakeFiles/tmx-loader.dir/src/MapLoaderPublic.cpp.o
[ 33%] Building CXX object CMakeFiles/tmx-loader.dir/src/MapLoaderPrivate.cpp.o
[ 41%] Building CXX object CMakeFiles/tmx-loader.dir/src/MapLayer.cpp.o
[ 50%] Building CXX object CMakeFiles/tmx-loader.dir/src/MapObject.cpp.o
[ 58%] Building CXX object CMakeFiles/tmx-loader.dir/src/QuadTreeNode.cpp.o
Linking CXX shared library libtmx-loader.so
[ 58%] Built target tmx-loader
Scanning dependencies of target BenchMark
[ 66%] Building CXX object CMakeFiles/BenchMark.dir/examples/Benchmark.cpp.o
Linking CXX executable BenchMark
libtmx-loader.so: undefined reference to `sf::Image::~Image()'
libtmx-loader.so: undefined reference to `sf::VertexArray::VertexArray(sf::PrimitiveType, unsigned long)'
libtmx-loader.so: undefined reference to `sf::VertexArray::operator[](unsigned long)'
libtmx-loader.so: undefined reference to `sf::RenderTarget::draw(sf::Vertex const*, unsigned long, sf::PrimitiveType, sf::RenderStates const&)'
collect2: error: ld returned 1 exit status
CMakeFiles/BenchMark.dir/build.make:91: recipe for target 'BenchMark' failed
make[2]: *** [BenchMark] Error 1
CMakeFiles/Makefile2:61: recipe for target 'CMakeFiles/BenchMark.dir/all' failed
make[1]: *** [CMakeFiles/BenchMark.dir/all] Error 2
Makefile:117: recipe for target 'all' failed
make: *** [all] Error 2
17:16:06, /home/linde/repos/sfml-tmxloader/build, (master) > 

Tried on debian jessie x64

Add support for animated tiles

It would be nice to eventually add support for animated tiles. This isn't a feature in Tiled so would need some serious consideration as to how animated tiles would be designated in the editor. Overall this feature is low priority but I would love input from anyone who has ideas about how this could be done.

Simple test fails: call for help

Hello user of sfml-tmxloader,

Both sfml-tmxloader and STP do not work anymore on a standard Tiled map. I suspect something upstream changed, but I have no clue.

Anybody has an idea?

I have created a test case on my fork. It loads a standard tiled map and checks that the number of layers is non-zero. It fails on that assert.

The test can be run with:

cd tests
./test.sh

@fallahn notified me of his full schedule, so who else can help me with pugixml?

I also submitted the same test to STP, that suffers the same problem, as a Pull Request, so I assume if one fixes the bug, it will be easier for the other to follow.

When the test is fixed on my fork, the Pull Request for fixing this bug can be accepted.

Thanks, Richel

MapObject setVisible ?

Hi,
Since i'm newbie with TmxLoader, I dunno how it is supposed to work but :

for (auto& layer : layers)
{
    if (layer.type == tmx::ObjectGroup)
    {
        for (auto& obj : layer.objects)
        {
            if (layer.name == "Collectable")
            {
                if (obj.Contains(animatedSprite.getPosition()))
                {
                   std::cout << "Test";
                   obj.SetVisible(false);
                }
            }
        }
    }
}

I've got the "Test" text in my cmd, but the object is still visible on the map, I really don't know what to think about it?
If anyone has suggestions, it would be really appreciated ! :)

Bug when adding another image layer to map

If another new image layer is added, then the previous sprite fails to show up (white square).

A reference to an element in a std::vector may become invalid when adding things to it, because the vector may need to resize itself and move to a different location in memory.

Animated Tile with Tiled Editor

Hi everybody,

I was wondering if there is a way to handle animated tiles as follow:
https://youtu.be/ZwaomOYGuYo?t=15m19s

Because when I add an animation, it is not shown as animated, so I guess it is not handle by the parser.

I've found this issue https://github.com/fallahn/sfml-tmxloader/issues/6
Unfortunately I've not found in which way Tiled add properties to an animated tile and how to get that property using the parser.

Do you have any idea?

I guess I have to get through all tiles and then check the property, if it is an animated tile, I just have to update the textureRect of the sprite to obtain the animation.

But what is the property for animated tiles?

Any help is appreciate 😄

Please add a Default Constructor that takes no addSearchPath() in Map Loader Class

I would like to see this added to map Loader

class MapLoader final : public sf::Drawable, private sf::NonCopyable
{
public:
MapLoader();
MapLoader(const std::string& mapDirectory);

in maplaoderpublic.cpp

//ctor
MapLoader::MapLoader()
: m_width(1u),
m_height(1u),
m_tileWidth(1u),
m_tileHeight(1u),
m_tileRatio(1.f),
m_mapLoaded(false),
m_quadTreeAvailable(false),
m_failedImage(false)
{
//reserve some space to help reduce reallocations
m_layers.reserve(10);
}
MapLoader::MapLoader(const std::string& mapDirectory)
: m_width (1u),
m_height (1u),
m_tileWidth (1u),
m_tileHeight (1u),
m_tileRatio (1.f),
m_mapLoaded (false),
m_quadTreeAvailable (false),
m_failedImage (false)
{
//reserve some space to help reduce reallocations
m_layers.reserve(10);

AddSearchPath(mapDirectory);

}

Give more control over quadtree elements

Hi. Thanks for this awesome library. Having a map loader with a built-in quad tree is really convenient. It would be nice to have more control over the quad's elements, though.

For instance, I'd like to be able to only add objects from a particular layer instead of all layers (or arbitrary combinations of layers/objects). I suppose I can do this now by using QuadTreeRoot directly, but I'd be ignoring the UpdateQuadTree and QueryQuadTree methods, which aren't strictly necessary.

Also nice would be using the quad tree class for anything providing a GetAABB method, not just Map Objects. For instance, I'd love to double dip and use it for tracking projectiles, for instance.

I think both of these can be resolved by breaking out the quad tree implementation into a template. It's arguable whether or not the MapLoader member functions should remain or be removed in favor of using the QuadTree directly.

What do you think?

Quadtree broken?

All objects in the quadtree are at the topmost level despite being trivial to partition, except for one object which cannot be found in the quadtree at all for some reason.

I can provide the TMX.

Debug info should be drawn for single layers

Currently the debug info can only be drawn for all layers, or no layer. It also incurs a dramatic performance hit. This could be updated to allow drawing of debug info per layer, and performance increased with the use of vertex arrays

"Collection of images" tileset type

First of all, thanks for the awesome library!

Now, the problem :p
The tmx format (and Tiled) provides another way of loading sprites: using collection of images.
This results on the following code being added to the final tmx file:

 <tileset firstgid="65" name="images" tilewidth="44" tileheight="42">
  <tile id="0">
   <image width="44" height="42" source="../sprites/image1.png"/>
  </tile>
  <tile id="1">
   <image width="44" height="42" source="../sprites/image2.png"/>
  </tile>
  <tile id="2">
   <image width="44" height="42" source="../sprites/image3.png"/>
  </tile>
 </tileset>

But when loading this with sfml-tmxloader, I'm getting this error: Missing image data in tmx file. Map not loaded. (found on https://github.com/fallahn/sfml-tmxloader/blob/master/src/MapLoaderPrivate.cpp#L191)

Any thoughts on this?

Object visibility property has no effect

This is caused by having all tile type objects drawn via a vertex array. The possible solutions would be to either go back to using sprites for tile objects, or providing an interface for attaching sprites to objects, so that an object layer can be made invisible and sprites drawn at will

MapObject::CollisionNormal: Invalid initialization of non-const ref

On GCC 4.8. Explicitly creating the vector first fixes the issue.

So the line (220):

return Helpers::Vectors::Normalize(sf::Vector2f(end - start));

becomes

sf::Vector2f tx(start-end);
return Helpers::Vectors::Normalize(tx);

The problem is in binding a non-const ref to a temporary, which is illegal according to the standard.

Thanks Matt!

I followed your guide on the wiki and got everything to work perfectly, I created a demonstration with a portable (machine independent) Visual Studio project/Demo here that can be used as a template for anyone who downloads the project along with a demonstration of how the camera can be used to traverse the TMX maps. Along with that I added a built version of Zlib for the x86 architecture to the project for people who have trouble building it. Thanks for all the help and i would love it if you left a link to the template in your project description ;).

Best Regards!

https://github.com/MossFrog/Tile_Map

PS: I will add a readme tommorow!

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.