2
\$\begingroup\$

I've been programming a final fantasy 6 clone in C# using Monogame and Monogame Extended, and have met on a few interesting challenges regarding tilemap collision.

The game seems to have different height levels on tilemaps, such as in the picture below where the bridge is on one height level and the ground on another. I'm using Tiled for my maps and have the bridge on it's own layer, and the ground on another. However, when it comes to collision, you shouldn't be able to for example walk up on the bridge and end up on the ground, which leads to the problem of collision detection. Collision for the ground level should be different than on another height level like the bridge, but I'm not sure what a good solution to handle that could be.

Since I'm using TiledMap from Monogame Extended, I can't really modify the Tile class to hold collision data. My initial idea was to have an extra object or tile layer for each height level to specify collision/solids for each height level, but I found that it wasn't very intuitive and that it was a little messy. Optimally I would only need one tile layer per height level, but I'm at a loss for any ideas on how to handle collision in a scalable and intuitive way, so I was wondering if anyone here had any ideas?

enter image description here

Another interesting problem is regarding tile collisions and directions. For example, when standing in front of the fence in the picture below, you should not be able to walk up and behind the fence. But, if you are standing one tile above the fence, you should be able to walk down and behind it, but once you are behind it you should not be able to walk down again and end up in front of it.

I think the solution to that problem is to define collisions on each edge of the tile, so that the bottom edge of the tile is marked as solid, while the other edges aren't. The main issue with that is that I have no idea how to implement something like that with Tiled. It also presents the problem of rendering, since the tile would need to be rendered below the player if the player stands in front of it, and above the player if the player stands behind it. I think using a Z-index would solve it, but again, I haven't found a way to implement that using Tiled. Soo, I was wondering if anyone has any ideas or pointers on how to use Tiled w/ Monogame + Monogame Extended to implement those things?

enter image description here

\$\endgroup\$
3
  • \$\begingroup\$ If i remember correctly rpgmaker let you things like this by soring some additional data per tile which determines how movement is allowed through it. Since RPG-maker was made to work with this type of map, maybe someone with more experience with it could point you in the right direction. \$\endgroup\$
    – Niels
    Commented Dec 22, 2017 at 12:30
  • \$\begingroup\$ I'm not using RPG Maker, but Tiled for creating tilemaps, and MonoGame Extended for loading and using the TMX files. \$\endgroup\$ Commented Dec 22, 2017 at 13:55
  • \$\begingroup\$ I meant that you could have a look at how RPG Maker solved the problem. \$\endgroup\$
    – Niels
    Commented Jan 2, 2018 at 8:47

1 Answer 1

0
\$\begingroup\$

I can't comment to any specific feature in monogame that will help you, but I can help you a bit with figuring out what needs to be done in general.

First you need some way of drawing certain tilesets over your character, there is no way around this, if your API doesn't allow z ordering, or different tile layers that can be drawn on top, you literally cannot do anything you want with out extending the API some how. Your in luck though since it appears you can orient render order on tilemaps.

You'll then need to have a separate data structure for collision, you wouldn't attach it to the tile map anyway. It seems that there are some collision classes included with monogame extended based on the github.

The collision data could be stored in a grid the size of your map with only boolean data of collidable and not collidable. This could be as simple as 2D array of boolean values.

You wouldn't just have one of these though, for each layer you would want one of these, for example top and ground portions of your first image.

To get the guard rail collision working with this system, you could simply make those places not collidable on the second level.

The only thing missing from this system so far is stairs. To get from one place to another you may want to change your collision array into an enum of tile properties for example:

enum TileMovement {
    Allowed, 
    Blocked, 
    StairsDown, 
    StairsUp,
    ...
}; 

and check if the tile is stairs, then move to the appropriate level after getting off the tile. You could also add other special tile types that would block from a given direction, but this would make your code more complicated (though could alleviate the need for additional levels on some maps)

StairsUp would be stairs that if you step onto you would end up at the next level, StairsDown would be stairs that if you step off of you would end up at a lower level.

\$\endgroup\$
2
  • \$\begingroup\$ I ended up solving this with one int array containing collision data in form of flags like SOLID, SOLID_DOWN, SOLID UP etc. I added directional passability data via tile properties in Tiled. I also added a z-index to each tile layer, which decides if layers should be renderer above or below the player. I haven't really implemented collision for different height levels, but it's just a matter of adding a new collision array for every height level as mentioned c: \$\endgroup\$ Commented Dec 26, 2017 at 22:26
  • \$\begingroup\$ @MysticSheik Glad I could help! \$\endgroup\$
    – Krupip
    Commented Dec 29, 2017 at 23:13

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .