monogame using Tiled tilemap

Does anybody know how the relation between monogame and a loaded Tiled (https://www.mapeditor.org/) map is made at code level?
How to implement this?

I load a Tiled tilemap using TiledCS (https://github.com/TheBoneJarmer/TiledCS) library and then draw it using monogame.

If I move my player accross the map, how do I know in what tile of the tilemap I am currently standing?
I want to know for example if i’m standing on grass or in water tile, so I know what actions I can do on the tile (in water I can swim, on grass I can put down an object, …)

1 Like

How about reading the docs first?

Very funny
There are NO monogame docs and certainly not about my question
Feel free to give links where you think are those mysterious docs related to my question!

2 Likes

Alex the Kidd?

Could you explain how your game is built?

Is it a platformer or a top down?

Are you detecting a tile behind the player or below?

You want to investigate Ray Casting as this will give you the objects collided, and then you can go from there, just look for XNA RayCasting / XNA Ray Casting guides and look for the code that brings up the objects that have been collided…

Keep in mind, you want to control how often a ray is cast as they tend to be performance hogs…

There are guides for the other question…

I agree that the documentation around this is somewhat lacking.
I took a quick look at monogame.extended.tileset as I am working on something similar to what you are doing.

Assuming the tile size is 32 and you are working in 2D:

You need to do something like:

Get the screen X, Y coordinates you want to check.
Convert X, Y to tile coordinates
TileX = X / 32
TileY = Y / 32

Then you need to drill down into the tileMap that you loaded using TileX and TileY as indexes.

something like:
myMap.Layers[n].Tiles[TileX, TileY];

For monogame.extended.tileset it looks like something like this should work for Layer 0 (untested):
var tile = map.TileLayers[0].GetTile(TileX, TileY);

You may need to iterate through each layer in the map dependent on what you want to do.

I expect its similar for TiledCS.

1 Like

can you give a complete code example please?
I can’t find it

I don’t have a working example yet - I will put something up when I do.

@lonely-unicorn

This displays text in the top left showing the X,Y and tile type currently under the mouse.

4 Likes

I downloaded the code to a separate folder to test it works.

There a few things to watch out for:
The content manager application has relative paths in the References.

To ensure the paths work, you need to Unzip the file into this folder:
C:\Users\YOURUSERNAME\source\repo

Load the solution into Visual Studio (I am using 2022 community edition).

Right click on Solution in the Solution Explorer pane and select “Restore nuget packages”.

Open the content manager and build it.

Build the solution.

1 Like

Fantastic! I was looking for the same.

There is a person here writing tutorials on github for monogame.
I think a Tiled tutorial could be made out of this.
Maybe you can contact him to add it?

Is it correct the tile type is the ID you can see in the tileset in Tiled map editor or am I wrong?

Would you maybe be so kind to add to this code example a layer to the existing map that define collision objects and a player you can move with the keyboard to show how collisions are done using monogame.extended?
I can’t figure it out.

Yes - its the Tile ID that you can see when you edit the tiles in Tiled application.

I am looking at collisions at the moment.
What I have done so far is:

  1. read in the Tiled map
  2. Go through all the tiles and add a rectangle to the monogame.extended.collisions object for each tile that I want to block the player.

This is working fine - but as you suggest, I think it would be better to use a separate layer on the map or alternatively, use a custom property on the tile to indicate it blocks.

image

1 Like

Thx! Please upload the example when ready :slight_smile:

I was also wondering if you know if there is a way to change a Tiled map using monogame.extended.
Can we change a tile type when a player moves over the tile and for example presses a key “T” to change the tile to another type? (or can maps only be read-only)

thx

Hi

I think the code example is not reading the tile type correctly.
If I compare to Tiled, I get wrong IDs.

Look at screenshot. The yellow color tiles are all type 15 as read by the code example.

But if I look in Tiled, tile with ID 15 is not completely yellow.
It has grass at the right side. So all yellow tiles can’t have ID 15 …
See below.

Good catch. I hit the same issue yesterday in my main project.
The issue is Tiled uses a start ID for each TileSet in the map called “firstGid”.

This allows multiple TileSets to be used in the same map.

The problem is, monogame.extended.Tiled is not making this firstGid attribute available in the code.
You can see it’s there in the map file (samplemap.tmx):
tileset firstgid=“1” source="[A]Grass_pipo.tsx"
tileset firstgid=“529” source="[A]Water_pipo.tsx"

If the TileId returned is 1-528, that means it’s in the first tileset.
If it’s > 529 its in the second tileset.

As we don’t have access to the 1 or 529, it’s impossible to tell which tile set.
According to the documentation, the first TileSet always has firstGid = 1 so for now, I have changed the code to just subtract 1 from the index which fixes the tiles from the first tileset (everything except the water).

    private void UpdateTileText(int x, int y)
    {
        if (ContainsXY(x, y))
        {
            int tileX, tileY;
            GetTileXYAtPoint(x, y, out tileX, out tileY);
            var tile = _tiledMap.TileLayers[0].GetTile((ushort)tileX, (ushort)tileY);
            _tileText = $"{tileX}, {tileY} TileType: [{tile.GlobalIdentifier - 1}]";      // Subtract firstGid (== 1) here
        }
    }

I can’t see how to support multiple tileSets at the moment without changing the monogame.extended.Tiled code.

Options:

  • Switch to another Tiled package such as TiledCS
  • Change monogame.extended.tiled and add firstGid to the class. I took a look at the code and it looks like it reads it in from the file so I may be missing something.

Tiled docs are here:
https://doc.mapeditor.org/en/stable/reference/tmx-map-format/#tmx-tileset

I have solved the issue now.
monogame.extended.tiled TiledMap class has this function:

public int GetTilesetFirstGlobalIdentifier(TiledMapTileset tileset)

The tileSet and tile offset can be found like this:

    private string GetTileText(TiledMap map, int id)
    {
        foreach (var tileSet in map.Tilesets)
        {
            int firstGid = map.GetTilesetFirstGlobalIdentifier(tileSet);

            if ((id >= firstGid) && (id < firstGid + tileSet.TileCount))
                return $"{tileSet.Name}: {id - firstGid}";
        }

        return "Unknown";            
    }

I have updated the Git repository.

Great! Thanks to your explanation, everything is very understandable now!
(this should be in the monogame.extended docs so everybody sees how it works)
For some reason monogame.extended adds “_0” to the name of a tileset, do you know why? (it’s not a real problem)
They are called Grass_pipo_0 and Water_pipo_0

Do you still want to make a collisions layer and a moving player by using monogame.extended?

  • I’m also interested in the most easy way of handling collisions (preferred by a layer which you don’t draw on the screen, but is just used for collisions)

  • I don’t know for sure how to know on what tile a moving player is currently standing. What method to use for this (instead of the mouse code)?

If interested, I would love to see both things above added (or another project if you don’t want to add it to this one)

Thanks in advance!

Hi

For some reason the water tiles all have ID 454 but some have ID 2758.
Do you have an idea why? Because the tiles are all the same.
If you look in the tileset 454 and 2758 seem to be identical too (how they look) but they have other IDs.

I made a screenshot and indicated in red the water that has ID 2758. All other water tiles have ID 454

Please let me know if you have an explanation for this.

thanks!
Lisa

Hi

I found a youtube video that shows collisions on a Tiled map by using TiledSharp.
Maybe you can use this to get an idea to make the same by using monogame.extended?
I understand how they do it, but don’t know the code for monogame.extended (they loop through the “collisions” layer)

Here is the github

Thx
Lisa