craftworkgames / MonoGame.Extended

Extensions to make MonoGame more awesome
http://www.monogameextended.net/
Other
1.42k stars 322 forks source link

TiledMapTileReader does not resolve object type TiledMapObjectType.Tile #934

Open Mephisztoe opened 2 weeks ago

Mephisztoe commented 2 weeks ago

I used Tiled to create a tiled map.

So that I can add static visual assets offgrid, I added an Object Layer and used the "T"-shortcut with on selected tiles.

You can see the result here: image

For now, it is not possible to make MonoGame.Extended just render an object layer the same way a tile layer is rendered, although loading and manually accessing its content is pretty much identical.

So I wanted to manually spritebatch the objects. When trying to identify the objects' source rectangles within their respective tilesheet, I noticed, that I am not able to access their global identifiers. Also, I noticed that the TilesMapTileReader does not populate the Tile property on the TiledMapTileObject which kind of seems like an issue to me.

Here is a little repro-solution (the assets being used are taken from one of the Kenney Game Asset Packs): ObjectLayerIssueRepro.zip

Mephisztoe commented 2 weeks ago

So apparently this one is sort of a duplicate of this one.

Here is how I fixed it for the moment:

  1. In Tiled, I edited the TileSheet and added a Class description. image

  2. By doing so, the tiles get added to the TileSheets' .tsx file.

    <?xml version="1.0" encoding="UTF-8"?>
    <tileset version="1.9" tiledversion="1.10.2" name="Roguelike_RPG" tilewidth="16" tileheight="16" spacing="1" tilecount="1767" columns="57">
    <image source="roguelikeSheet_transparent.png" width="968" height="526"/>
    <tile id="420" class="Decoration"/>
    <tile id="478" class="Decoration"/>
    <tile id="482" class="Decoration"/>
    </tileset>
  3. Because the TiledMapTileReader can now populate the Tiled property of the TileMapTileObject objects, I can now retrieve their source rectangles and draw them properly

private void DrawObjectLayer(SpriteBatch spriteBatch, TiledMap tiledMap)
{
    foreach (var obj in decorationLayer.Objects)
    {
        if (obj is TiledMapTileObject tileObject)
        {
            var tileset = tileObject.Tileset;
            var localIdentifier = tileObject.Tile.LocalTileIdentifier;
            var tileHeight = tileset.TileHeight;             

            var sourceRectangle = tileset.GetTileRegion(localIdentifier);

            var position = new Vector2(tileObject.Position.X, tileObject.Position.Y - tileHeight);

            spriteBatch.Draw(tileset.Texture, position, sourceRectangle, Color.White);
        }
    }
}

Result: image

However, I'd vote for ninjeffs suggestion here.